416. 分割等和子集
动态规划:01背包
java
class Solution {
public boolean canPartition(int[] nums) {
//01背包
//子问题:能不能从nums里选出总和为sum/2的数
//dp[i]指的是已遍历的数中可不可以凑出总和为i的值
//状态方程:dp[i] = dp[i] || dp[i-num]
//倒序遍历,防止在同一轮中用数两次
int n = nums.length;
int sum = 0;
for(int i = 0;i<n;i++){
sum+=nums[i];
}
//奇数不行
if(sum%2 != 0){
return false;
}
int target = sum/2;
boolean[] dp = new boolean[target+1];
//不选数就是0
dp[0] = true;
for(int num:nums){
for(int j = target;j>=num;j--){
dp[j] = dp[j] || dp[j-num];
}
}
return dp[target];
}
}
时间复杂度:O(N*target)
空间复杂度:O(target)