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.
题目链接:https://leetcode-cn.com/problems/partition-equal-subset-sum/
思路
法一:set帮助查找
比较容易想到的方法,相当于暴力法的储存版,仅比暴力法快一丢丢。
用一个set记录当前所有数值组合的情况,新数字来是查看之前是否有匹配的上的。
时/空复杂度高,每次更新状态费时。
class Solution {
public:
bool canPartition(vector<int>& nums) {
int len = nums.size();
if(len<=1) return false;
int sum = accumulate(nums.begin(),nums.end(),0);
if(sum%2) return false;
sum /= 2;
unordered_set<int> rec;
for(int i=0; i<len; ++i){
if(sum==nums[i] || rec.find(sum-nums[i])!=rec.end()) return true;
for(auto iter=rec.begin(); iter!=rec.end(); ++iter){
rec.insert(*iter+nums[i]);
}
rec.insert(nums[i]);
}
return false;
}
};
法二:dp
其实相当于是从法一的set查找过程,变成了数组下标访问。
因为这题限制了正整数,因此不会出现负数的和,所以可以利用数组记录。
class Solution {
public:
bool canPartition(vector<int>& nums) {
int len = nums.size();
if(len<=1) return false;
int sum = accumulate(nums.begin(),nums.end(),0);
if(sum%2) return false;
sum /= 2;
bool rec[sum+1] = {false};
rec[0] = true;
for(int i=0; i<len; ++i){
for(int j=sum; j>=nums[i]; --j){
if(rec[j-nums[i]]) {
rec[j] = true;
if(j==sum) return true;
}
}
}
return false;
}
};