当前位置:网站首页>动态规划——416. 分割等和子集
动态规划——416. 分割等和子集
2022-07-28 03:21:00 【向着百万年薪努力的小赵】
1 题目描述
给你一个 只包含正整数 的 非空 数组 nums 。请你判断是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。
2 题目示例
示例 1:
输入:nums = [1,5,11,5]
输出:true
解释:数组可以分割成 [1, 5, 5] 和 [11] 。
示例 2:
输入:nums = [1,2,3,5]
输出:false
解释:数组不能分割成两个元素和相等的子集。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/partition-equal-subset-sum
3 题目提示
1 <= nums.length <= 200
1 <= nums[i] <= 100
4 思路
本体思路来源代码随想录
链接:https://programmercarl.com/0416.%E5%88%86%E5%89%B2%E7%AD%89%E5%92%8C%E5%AD%90%E9%9B%86.html#_01%E8%83%8C%E5%8C%85%E9%97%AE%E9%A2%98
背包问题,大家都知道,有N件物品和一个最多能背重量为W 的背包。第i件物品的重量是weight[i],得到的价值是value[i] 。每件物品只能用一次,求解将哪些物品装入背包里物品价值总和最大。
背包问题有多种背包方式,常见的有:01背包、完全背包、多重背包、分组背包和混合背包等等。
要注意题目描述中商品是不是可以重复放入。
即一个商品如果可以重复多次放入是完全背包,而只能放入一次是01背包,写法还是不一样的。
要明确本题中我们要使用的是01背包,因为元素我们只能用一次。
回归主题:首先,本题要求集合里能否出现总和为 sum / 2 的子集。
那么来一一对应一下本题,看看背包问题如果来解决。
只有确定了如下四点,才能把01背包问题套到本题上来。
背包的体积为sum / 2
背包要放入的商品(集合里的元素)重量为 元素的数值,价值也为元素的数值
背包如果正好装满,说明找到了总和为 sum / 2 的子集。
背包中每一个元素是不可重复放入。
以上分析完,我们就可以套用01背包,来解决这个问题了。
动规五部曲分析如下:
- 确定dp数组以及下标的含义
01背包中,dp[j] 表示: 容量为j的背包,所背的物品价值可以最大为dp[j]。
套到本题,dp[j]表示 背包总容量是j,最大可以凑成j的子集总和为dp[j]。 - 确定递推公式
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]); - dp数组如何初始化
在01背包,一维dp如何初始化,已经讲过,
从dp[j]的定义来看,首先dp[0]一定是0。
如果如果题目给的价值都是正整数那么非0下标都初始化为0就可以了,如果题目给的价值有负数,那么非0下标就要初始化为负无穷。
这样才能让dp数组在递归公式的过程中取的最大的价值,而不是被初始值覆盖了。
本题题目中 只包含正整数的非空数组,所以非0下标的元素初始化为0就可以了。 - 确定遍历顺序
在动态规划:关于01背包问题,你该了解这些!(滚动数组) (opens new window)中就已经说明:如果使用一维dp数组,物品遍历的for循环放在外层,遍历背包的for循环放在内层,且内层for循环倒序遍历! - 举例推导dp数组
dp[j]的数值一定是小于等于j的。
如果dp[j] == j 说明,集合中的子集总和正好可以凑成总和j,理解这一点很重要。
5 我的答案
class Solution {
public boolean canPartition(int[] nums) {
if(nums == null || nums.length == 0) return false;
int n = nums.length;
int sum = 0;
for(int num : nums){
sum += num;
}
//总和为奇数,不能平分
if(sum % 2 != 0) return false;
int target = sum / 2;
int[] dp = new int[target + 1];
for(int i = 0; i < n; 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]);
}
}
return dp[target] == target;
}
}
边栏推荐
- MySQL stored procedures use cursors to synchronize data between two tables
- [5g NR] RRC reject analysis
- D2DEngine食用教程(4)———绘制文本
- 一键重装win7系统详细教程
- 什么是虚函数?
- Redis source code analysis (who says C language can't analyze it?)
- Contour detection based on OpenCV (3)
- What is a virtual function?
- 如何使用JDBC操作数据库
- How does win11 display fixed applications?
猜你喜欢

Outlook tutorial, how to use color categories and reminders in outlook?

如何让外网访问内网IP(esp8266网页使用)

Shell:资源监控脚本和高负载报警

Unity backpack system

Redis source code analysis (who says C language can't analyze it?)

Tensorboard usage record

「运维有小邓」网络设备监控

12月份PMP考试首次采用新考纲,该怎么学?

C language to achieve a dynamic version of the address book

IronOCR for .NET 2022.8
随机推荐
Uniapp - make phone calls and send text messages
STM32 RT-Thread虚拟文件系统挂载操作
How to solve the problem of win11 black desktop background?
2022最新Android Handler相关面试题总结
什么是虚函数?
叶子识别 颜色的特征提取 缺陷检测等
Response to questions about the balanced beacon group of Hubei University of Arts and Sciences
xctf攻防世界 Web高手进阶区 unserialize3
IronOCR for .NET 2022.8
C language to achieve a dynamic version of the address book
Summary of redis classic interview questions
图文并茂:JVM 内存布局详解
When a dialog box pops up, the following form is not available
ThreadLocal usage scenario
[5g NR] RRC reject analysis
整合SSM实现增删改查搜索
过亿资产地址被拉入黑名单?Tether地址冻结功能该怎么用?
Detailed tutorial of one click reinstallation of win7 system
SQL Server备份数据库的方法
Outlook tutorial, how to use color categories and reminders in outlook?