416. 分割等和子集
简单0-1背包
class Solution {
public boolean canPartition(int[] nums) {
int sum = 0;
for(int num : nums){
sum += num;
}
// base case
if(sum % 2 != 0)return false;
int target = sum / 2;
// dp[i]: 重量为i的背包最多装下的物品价值
// nums[i]: 物品的重量和价值
int[] dp = new int[target + 1];
for(int i = 0; i < nums.length; i++){
for(int j = target; j >= nums[i]; j--){
dp[j] = Math.max(dp[j], dp[j - nums[i]] + nums[i]);
}
// 剪枝,每一次完成内层的for-loop,检查是否等于目标值,优化时间复杂度
if(dp[target] == target)return true;
}
return dp[target] == target;
}
}
0-1背包压缩到一维时,外层遍历物品,内层遍历背包,且内从从后向前遍历以确保每件物品最多只被添加一次。