LeetCode/solutions/416. Partition Equal Subset Sum.md
2019-11-19 23:47:11 +08:00

33 lines
1.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# [416. Partition Equal Subset Sum](https://leetcode.com/problems/partition-equal-subset-sum/)
# 思路
给定一个数组,问这个数组能不能分成两个非空子集合,使得两个子集合的元素之和相同。两个集合元素和相同,也就是都等于所有元素和的一半。
即题目转换成从数组里面选取若干数字使和为一个定值。另外如果所有元素和为奇数的话直接返回false。
## 思路一
我们可以采用一个bitset来记录所有可能的和。具体步骤是
开辟一个大小为5001的bisets因为所有元素和不超过10000名为bits最后得到的bits满足`bits[i]=1`则代表nums中某些元素的和为i最后判断bits[sum/2]是否为1即可。处理方法为
初始时`bits[0] = 1`然后从前往后遍历nums数组对于当前遍历到的数字num把 bits 向左平移 num 位,然后再或上原来的 bits这样就代表在原先的基础上又新增了一个和的可能性。
比如对于数组 [1,3],初始化 bits 为 ...00001遍历到1bits 变为...00011然后遍历到3bits 变为了 ...11011。最终得到的bit在第1,3,4位上为1代表了可能的和为1,3,4这样遍历完整个数组后去看 bits[sum/2] 是否为1即可。
## 思路二
其实本题也可以看做是一个01背包问题改天对背包问题做个总结先占个坑。
# C++
## 思路一
``` C++
class Solution {
public:
bool canPartition(vector<int>& nums) {
bitset<5001>bits(1);
int sum = accumulate(nums.begin(), nums.end(), 0);
if(sum & 1) return false; // sum为奇数
for (int &num : nums) bits |= (bits << num);
return bits[sum >> 1];
}
};
```