给定一个只包含正整数的非空数组。是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。
注意:
每个数组中的元素不会超过 100
数组的大小不会超过 200
示例 1:
输入: [1, 5, 11, 5]
输出: true
解释: 数组可以分割成 [1, 5, 5] 和 [11].
示例 2:
输入: [1, 2, 3, 5]
输出: false
解释: 数组不能分割成两个元素和相等的子集.
class Solution {
public:
int memo[20001];
bool dfs(int pos,int target,vector<int>& nums){
if(target<0) return false;
if(target==0) return true;
for(int i = pos;i<nums.size();i++){
if(memo[target]) return false;
if(dfs(i+1,target-nums[i],nums)) return true;
}
memo[target] = 1;
return false;
}
bool canPartition(vector<int>& nums) {
int sum = 0;
for(int i = 0;i<nums.size();i++) sum+=nums[i];
if(sum&1) return false;
int target = sum/2;
return dfs(0,target,nums);
}
};
动态规划
class Solution {
public:
bool canPartition(vector<int>& nums) {
int sum = 0;
for(int i = 0;i<nums.size();i++) sum+=nums[i];
if(sum&1) return false;
int target = sum/2;
vector<vector<bool>> dp(nums.size()+1,vector<bool>(target+1,false));
for (int i = 0; i <= nums.size(); i++) dp[i][0] = true;
for(int i = 1;i<=nums.size();i++){
for(int j = 1;j<=target;j++){
if(nums[i-1]>j) dp[i][j] = dp[i-1][j];
else dp[i][j] = dp[i-1][j]|dp[i-1][j-nums[i-1]];
}
}
return dp[nums.size()][target];
}
};