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:

  1. Each of the array element will not exceed 100.
  2. 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];
    }

};

参考链接:Concise C++ Solution summary with DFS, DP, BIT

posted @ 2018-06-24 08:11  妖域大都督  阅读(111)  评论(0编辑  收藏  举报