416. Partition Equal Subset Sum
问题描述:
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.
解题思路:
首先我们可以对数组求和,求和后判断能否被2整除,如果不能被二整除,那么绝对不可能分成两个集合且每个集合的和相等。
若可以被二整除,我们进一步讨论是否有这样的集合存在。 target = sum>>2
一开始我想用DFS来做这道题,就是找数组中是否有数字的和为target。
过不了OJ( ・᷄ὢ・᷅ )
朋友们,每当这时候,我们要想想,能不能用DP做呀?
dp[i]代表数组中是否存在集合使得和为i。
对数组nums中每一个数字num:
dp[i] = dp[i] || dp[i - num]
那i如何取值呢?
因为我们想要返回的是dp[target]
所以可以令 i = target。
此时含义为,num和其之前的数字能够组成和为target的集合吗?
变换方式为i--,直至i == num(为了避免出现负数)
还有位操作的方法:参考GrandYang
重点:把bits向左平移num位,然后再或上原来的bits,这样所有的可能出现的和位置上都为1
代码:
class Solution { public: bool canPartition(vector<int>& nums) { int sum = accumulate(nums.begin(), nums.end(), 0), target = sum >> 1; if (sum & 1) return false; vector<int> dp(target + 1, 0); dp[0] = 1; for(auto num : nums) for(int i = target; i >= num; i--) dp[i] = dp[i] || dp[i - num]; return dp[target]; } };