LeetCode刷题 Day42
416. Partition Equal Subset Sum
Given a non-empty array nums containing only positive integers, find if the array can be partitioned into two subsets such that the sum of elements in both subsets is equal.
Example 1:
Input: nums = [1,5,11,5]
Output: true
Explanation: The array can be partitioned as [1, 5, 5] and [11].
Example 2:
Input: nums = [1,2,3,5]
Output: false
Explanation: The array cannot be partitioned into equal sum subsets.
思路:
- 这是典型的背包问题, 背包的最大容量为 nums和的一半,
- 首先要考虑dp中j和dp[j]的意义,j为背包容量,dp[j]为当前容量下的最大和
- 递推公式,因为为典型的背包问题,所以就可以从是否放入背包的角度考虑
- 未放入背包则继续使用上一个物品的dp值,也就是dp[j]。
- 放入背包dp[j - num] + num。
- 初始化dp: 因为是sum的一半,这样 dp = Array(sum / 2 + 1).fill(0), dp[0]是0, 因为背包容量为0的时候 最大和肯定也是0
- 遍历顺序: 这道题的遍历顺序是一个关键,因为对于一维(滚动)数组的dp,要考虑到物品“价值"是否重复加入: 当顺序遍历背包的时候,会导致物品的重复加入,因为这是一维数组,会被之前得到的值覆盖掉。 当逆序遍历背包的时候,初始值是0, dp[n]得到值不会滚动(累计)到dp[n - 1]中。
- 举例论证
代码:
var canPartition = function(nums) {
let sum = nums.reduce((a, b) => a + b);
if (sum % 2 === 1) return false;
sum /= 2;
let dp = Array(sum + 1).fill(0);
for (let num of nums) {
for (let j = sum; j >= num; j--) {
dp[j] = Math.max(dp[j], dp[j - num] + num);
}
}
if (dp[sum] === sum) return true;
return false;
};
时间复杂度: O(n2), 空间复杂度: O(n)