力扣刷题day35|416分割等和子集

news2024/10/6 6:44:44

416. 分割等和子集

力扣题目链接

给你一个 只包含正整数非空 数组 nums 。请你判断是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。

示例 1:

输入:nums = [1,5,11,5]
输出:true
解释:数组可以分割成 [1, 5, 5] 和 [11] 。

示例 2:

输入:nums = [1,2,3,5]
输出:false
解释:数组不能分割成两个元素和相等的子集。

思路

可以将这个数组分割成两个子集,使得两个子集的元素和相等。

那么只要找到集合里能够出现 sum / 2 的子集总和,就算是可以分割成两个相同元素和子集了。

本题可以用01背包来解决(元素只能用一次)

所以现在题目变为:要求集合里能否出现总和为 sum / 2 的子集。

那么来一一对应一下本题,看看背包问题如何来解决。

只有确定了如下四点,才能把01背包问题套到本题上来。

  • 背包的体积为sum / 2
  • 背包要放入的商品(集合里的元素)重量为 元素的数值,价值也为元素的数值
  • 背包如果正好装满,说明找到了总和为 sum / 2 的子集。
  • 背包中每一个元素是不可重复放入。

动态规划五部曲

  1. 确定dp数组以及下标的含义

01背包中,dp[j] 表示: 容量为j的背包,所背的物品价值可以最大为dp[j]。

套到本题,dp[j]表示 背包总容量是j,最大可以凑成j的子集总和为dp[j]

  1. 确定递推公式

01背包的递推公式为:dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);

本题,相当于背包里放入数值,那么物品i的重量是nums[i],其价值也是nums[i]。

所以递推公式:dp[j] = max(dp[j], dp[j - nums[i]] + nums[i]);

  1. dp数组如何初始化

从dp[j]的定义来看,首先dp[0]一定是0。

如果如果题目给的价值都是正整数那么非0下标都初始化为0就可以了,如果题目给的价值有负数,那么非0下标就要初始化为负无穷。

这样才能让dp数组在递归公式的过程中取的最大的价值,而不是被初始值覆盖了

本题题目中 只包含正整数的非空数组,所以非0下标的元素初始化为0就可以了。

int[] dp = new int[target + 1];

数组大小只用nums总和的一半,加上一个0

  1. 确定遍历顺序

如果使用一维dp数组,物品遍历的for循环放在外层,遍历背包的for循环放在内层,且内层for循环倒序遍历

// 开始 01背包
for (int i = 0; i < nums.length; i++) {
    for (int j = target; j >= nums[i]; j--) {
        //物品 i 的重量是 nums[i],其价值也是 nums[i]
        dp[j] = Math.max(dp[j], dp[j - nums[i]] + nums[i]);
    }
}
  1. 举例推导dp数组

dp[j]的数值一定是小于等于j的。

如果dp[j] == j 说明,集合中的子集总和正好可以凑成总和j

以示例1为例:

image-20221101191439014

最后dp[11] == 11,说明可以将这个数组分割成两个子集,使得两个子集的元素和相等。

完整代码

public boolean canPartition(int[] nums) {
    int sum = 0;
    for (int num : nums) {
        sum += num;
    }
    // 如果和为奇数,肯定不能平分
    if (sum % 2 != 0) {
        return false;
    }
    // 不为奇数就新设置一个target
    int target = sum / 2;

    int[] dp = new int[target + 1];
    // 开始 01背包
    for (int i = 0; i < nums.length; i++) {
        for (int j = target; j >= nums[i]; j--) {
            //物品 i 的重量是 nums[i],其价值也是 nums[i]
            dp[j] = Math.max(dp[j], dp[j - nums[i]] + nums[i]);
        }
    }
    // 集合中的元素正好可以凑成总和target
    if (dp[target] == target) return true;
    return false;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/461719.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

keil设置程序起始地址及生成bin文件的方法

一.keil设置程序起始地址 1.1FLASH APP 的起始地址设置 随便打开一个之前的实例工程&#xff0c;点击 Options for Target→Target 选项卡 默认的条件下&#xff0c;图中 IROM1 的起始地址&#xff08;Start&#xff09;一般为 0X08000000&#xff0c;大小&#xff08;Size&a…

通用el-table 修改样式

通用el-table 修改样式 el-table实现下图效果: <template><div class"contentbox"><el-table:data"tableData"height"310"style"width: 40%"highlight-current-rowcurrent-change"handleCurrentChange"&g…

利用Floodlight进行DDOS攻击防御实验笔记

Floodlight Floodlight是Apache授权并基于JAVA开发的企业级OpenFlow控制器&#xff0c;当前最新版本是1.2。 Floodlight OpenFlow Controller -ProjectFloodlight&#xff1a;http://www.projectfloodlight.org/floodlight/ 流表 把同一时间&#xff0c;经过同一网络中具有某种…

线程同步方式之二条件变量

Linux线程同步方法之二 条件变量 饥饿状态&#xff1a;由于线程A频繁地申请/释放锁&#xff0c;而导致其他线程无法访问临界资源的情况。 同步synchronized&#xff1a;在保证数据安全的前提下&#xff0c;让线程能够按照某种特定的顺序访问临界资源&#xff0c;从而有效避免…

Spring Security实战(九)—— 使用Spring Security OAuth实现OAuth对接

一、OAuth2.0介绍 OAuth2.0是一种授权协议&#xff0c;允许用户授权第三方应用程序代表他们获取受保护的资源&#xff0c;如个人信息或照片等。它允许用户授权访问他们存储在另一个服务提供商上的资源&#xff0c;而无需将其凭据共享给第三方应用程序。OAuth2.0协议建立在OAuth…

直升机空气动力学基础--004翼型的阻力

来源 1. 空气的粘性 2.阻力的产生 3.形成因素 4.阻力系数曲线

LeetCode-242. 有效的字母异位词

题目链接 LeetCode-242. 有效的字母异位词 题目描述 题解 题解一&#xff08;Java&#xff09; 作者&#xff1a;仲景 首先&#xff0c;满足条件的情况下&#xff0c;两个字符串的长度一定是相等的&#xff0c;不相等一定不满足条件 使用Hash表来存储字符串s中各个字符出现的…

回溯算法——我欲修仙(功法篇)

个人主页&#xff1a;【&#x1f60a;个人主页】 系列专栏&#xff1a;【❤️我欲修仙】 系列文章目录 第一章 ❤️ 学习前的必知知识 第二章 ❤️ 二分查找 文章目录 系列文章目录回溯算法&#x1f914;&#x1f914;&#x1f914;回溯算法一般可以解决的问题回溯算法的实现回…

Python语言简介

B站讲解视频&#xff1a;https://www.bilibili.com/video/BV1Mv4y1n7n8/?vd_source515e6808c21c69114a4fae34589dfb0e Python是什么 Python是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。具有很强的可读性&#xff0c;相比其他语言经常使用英文关键字&a…

为什么有时候磁珠会使电源的纹波变大

电路设计时&#xff0c;我们常常在芯片电源的输入放一个磁珠和电容&#xff0c;用以滤除电源上的高频噪声。 但是有时候会发现&#xff0c;加了磁珠后&#xff0c;芯片电源输入处纹波竟然变大了&#xff0c;超出了电源纹波范围&#xff0c;导致芯片工作异常。 把磁珠换成0R电阻…

论文阅读:Heterogeneous Graph Contrastive Learning for Recommendation(WSDM ’23)

论文链接 Motivation&#xff1a; 在推荐系统中&#xff0c;图神经网络在建模图结构数据上已经变成一个强有力的工具。但是现实生活的推荐语义通常涉及异质关系&#xff08;像用户的社交关系&#xff0c;物品知识关系的依赖&#xff09;&#xff0c;这些都包含丰富的语义信息…

Linux下实现C语言程序

一.情况说明 写这篇博客的情况比较复杂&#xff0c;首先我本来是参加新星计划按照规划现在去学习shell脚本语言的&#xff0c;但是博主现在由于其他原因需要了解makefile&#xff0c;makefile是Linux系统下的一种工具&#xff0c;makefile的一些背景要涉及链接库的知识&#xf…

从0开始搭建一个简单的前后端分离的XX系统-vue+Springboot+mybatis-plus+mysql

一、准备工作 1.安装node 2.idea 旗舰版** idea**教程 上述教程中的idea**工具 3.安装mysql任意版本 mysql 4.安装mysql workbench&#xff08;没用上&#xff09; 5.安装navicate 参考文章&#xff1a;百度-从小白到架构&#xff08;作者&#xff09;-Navicat16** Nav…

Thinkphp获取项目最近更改变动的所有文件

导读&#xff1a; 企业级的网站项目都是要不断优化迭代更新的&#xff0c;做为一名后端程序员&#xff0c;在编写更新模块时&#xff0c;如何能快速获取最近修改的文件&#xff0c;然后打包压缩成更新补丁呢&#xff1f;我们先来看一下最终效果图&#xff1a; 步骤&#xff1a…

使用FFMPEG分离mp4/flv文件中的264视频和aac音频

准备 ffmpeg 4.4 一个MP4或flv格式的视频文件 分离流程 大致分为以下几个简单步骤&#xff1a; 1.使用avformat_open_input 函数打开文件并初始化结构AVFormatContext 2.查找是否存在音频和视频信息 3.构建一个h264_mp4toannexb比特流的过滤器&#xff0c;用来给视频avpa…

Hudi 数据湖技术之集成Flink

目录 1 安装Flink2 快速入门2.1 集成Flink概述2.2 环境准备2.3 创建表2.4 插入数据2.5 查询数据2.6 更新数据 3 Streaming query3.1 创建表3.2 查询数据3.3 插入数据 4 Flink SQL Writer4.1 Flink SQL集成Kafka4.2 Flink SQL写入Hudi4.2.1 创建Maven Module4.2.2 消费Kafka数据…

【C++】了解设计模式、 stackqueue的使用与模拟实现

文章目录 1.设计模式2.stack1.stack的使用1.stack的结构2.stack的接口 2.stack的模拟实现1.stack的结构2.接口实现 3.queue1.queue的使用1.queue的结构3.queue的接口 2.queue的模拟实现1.queue的结构2.接口实现 4.了解deque1.deque的原理介绍2.deque的底层结构3.deque的迭代器设…

Codeforces Round 861 (Div. 2)(A~D)

A. Lucky Numbers 给出边界l和r&#xff0c;在区间[l, r]之间找到幸运值最大的数字。一个数字的幸运值被定义为数位差的最大值&#xff0c;即数字中最大的数位和最小的数位的差。 思路&#xff1a;因为涉及到至少两位&#xff0c;即个位和十位变化最快&#xff0c;最容易得到相…

Android四大组件之广播接收者BroadcastReceiver

一、全局广播 Android中的广播可以分为两种类型&#xff1a;标准广播和有序广播 标准广播&#xff1a;一种完全异步执行的广播&#xff0c;在广播发出之后&#xff0c;所有的广播接收器几乎都会同一时刻接收到这条广播消息&#xff0c;因此它们之间没有任何先后顺序。无法进行…

Vector-常用CAN工具 - 入门到精通 - 专栏链接

一、CANoe篇 1、CANoe入门到精通_软件安装 2、CANoe入门到精通_硬件及环境搭建 3、CANoe入门到精通_软件环境配置 4、CANoe入门到精通_Network Node CAPL开发 5、CANoe入门到精通_Node节点开发基本数据类型 6、CANoe入门到精通_Test Node节点开发设置 7、CANoe入门到精通…