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

1.7 KiB
Raw Blame History

416. 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++

思路一

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];
    }
};