LeetCode/分割等和子集
给你一个只包含正整数的非空数组 nums 。请你判断是否可以将这个数组分割成两个子集,使得两个子集的元素和相等
1. 回溯法(超时)
class Solution {
public:
bool canPartition(vector<int>& nums) {
//其实就是找一个集合值为特定值
int sum = accumulate(nums.begin(),nums.end(),0);
if(sum%2==1) return false;
sort(nums.begin(),nums.end());
if(nums.back()>sum/2) return 0;
return backtrack(0,sum/2,nums);
}
bool backtrack(int index,int target,vector<int>& nums){
if(target==0) return true;
for(int i = index;i<nums.size();i++){
if(target-nums[i]<0) return false;
if(backtrack(i+1,target-nums[i],nums)) return true;
}
return false;
}
};
2. 动态规划
本质上是一个背包问题,与之前写过的零钱兑换以及目标和十分相似
class Solution {
public:
bool canPartition(vector<int>& nums) {
//其实就是找一个集合值为特定值
int sum = accumulate(nums.begin(),nums.end(),0);
if(sum%2==1) return false;
int target = sum/2;
vector<bool> dp(target+ 1);
dp[0] = 1;
for (int& num : nums) {
for (int j = target; j >= num; j--) {
dp[j] = dp[j]|dp[j - num];
if(dp[target]==1) return true;//提前结束
}
}
return dp[target];
}
};