给定一个只包含正整数的非空数组。是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。
注意:
- 每个数组中的元素不会超过 100
- 数组的大小不会超过 200
示例 1:
输入: [1, 5, 11, 5] 输出: true 解释: 数组可以分割成 [1, 5, 5] 和 [11].
示例 2:
输入: [1, 2, 3, 5] 输出: false 解释: 数组不能分割成两个元素和相等的子集.
基本思路:当数组能分成两个相等的子数组时,必定是偶数,且其值必定为总和的一半,令其为target,此时,问题转换成在数组中求和为target的子数组,一个很明显的动态规划问题。
bool canPartition(vector<int>& nums) {
int target=0;
for(auto it:nums)
target+=it;
if(target&1) //若为odd,一定不可能分成两个相等的子数组
return false;
target=target>>1;
vector<int> dp(target+1,0);
dp[0]=1;
if(nums[0]<=target)
dp[nums[0]]=1;
for(int i=1;i<nums.size();i++)
for(int j=target;j>=nums[i];j--){
dp[j]=dp[j]||dp[j-nums[i]];
if(dp[target])
return true;
}
return false;
}