Given a non-empty array containing only positive integers, find if the array can be partitioned into two subsets such that the sum of elements in both subsets is equal.
Note:
- Each of the array element will not exceed 100.
- The array size will not exceed 200.
Example 1:
Input: [1, 5, 11, 5] Output: true Explanation: The array can be partitioned as [1, 5, 5] and [11].
Example 2:
Input: [1, 2, 3, 5] Output: false Explanation: The array cannot be partitioned into equal sum subsets.
class Solution {
public:
bool canPartition(vector<int>& nums) {
/*如果能划分 那么原数组的和一定是偶树 -> 问题转化为能否在数组中找到一个子集使其和等于总和的一半
* 进一步转化为: 背包问题 dp[i] 表示能找到一个子数组,该子数组的和为i
* dp[j] = dp[j] || dp[j-num]
* */
int sum = accumulate(nums.begin(), nums.end(), 0), target=sum>>1; // 左移等价于除2
if(sum & 1) return false; // 奇数和1按位取与 最后得到1
vector<bool> dp(target+1, false);
dp[0] = true; // 对当前能遍历到的num 对应的dp[num] 赋值
for(auto &num : nums){
for(int i=target;i>=num;i--){ // 一定要反向遍历 这样确保当前使用的dp[i-num]是之前求得的
dp[i] = dp[i] || dp[i-num];
}
}
return dp[target];
}
};