416. 分割等和子集

416. 分割等和子集

给定一个只包含正整数非空数组。是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。

注意:

  1. 每个数组中的元素不会超过 100
  2. 数组的大小不会超过 200

示例 1:

输入: [1, 5, 11, 5]

输出: true

解释: 数组可以分割成 [1, 5, 5] 和 [11].

 

示例 2:

输入: [1, 2, 3, 5]

输出: false

解释: 数组不能分割成两个元素和相等的子集.

 

方法一:回溯+剪枝

bool ArraySum(vector<int>& nums, int idx, int recive, int pass ){
        if(recive==0 || pass==0 )return true;
        if(recive<0 || pass<0 )return false;
        return ArraySum(nums , idx-1 , recive-nums[idx],pass)||ArraySum(nums, idx-1, recive , pass-nums[idx]);
    }

    bool canPartition(vector<int>& nums) {
        int sum=0;
        for(int i=0;i<nums.size();i++)
            sum+=nums[i];
        if(sum%2==1)return false;
        else
            sum/=2;
        sort(nums.begin(),nums.end());
        return ArraySum(nums,nums.size()-1,sum,sum); 
    }

 

 方法二:动态规划

bool canPartition(vector<int>& nums) {
        int sum=0;
        for(int k : nums) sum+=k;
        if(sum & 1)return false;
        else 
            sum>>=1;
        vector<bool> dp(sum+1,false);
        for(int i=0;i<nums.size();i++)
            for(int j=sum;j>=1;j--){
                if(nums[i]==j)dp[j]=1;
                else if(j>nums[i])
                    dp[j]=dp[j]||dp[j-nums[i]];         
            }
        return dp[sum];
    }

 

不知道是不是测试用例的关系,方法一的耗时是真的香,仅4ms,而方法二500ms

posted @ 2020-04-18 10:43  鳄鱼四驱车  阅读(231)  评论(0编辑  收藏  举报