LeetCode/分割等和子集

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

1. 回溯法(超时)

class Solution {
public:
    bool canPartition(vector<int>& nums) {
        //其实就是找一个集合值为特定值
        int sum = accumulate(nums.begin(),nums.end(),0);
        if(sum%2==1) return false;
        sort(nums.begin(),nums.end());
        if(nums.back()>sum/2) return 0;
        return backtrack(0,sum/2,nums);
    }
    bool backtrack(int index,int target,vector<int>& nums){
        if(target==0) return true;
        for(int i = index;i<nums.size();i++){
            if(target-nums[i]<0) return false;
            if(backtrack(i+1,target-nums[i],nums)) return true;
        }
        return false;
    }
};

2. 动态规划

本质上是一个背包问题,与之前写过的零钱兑换以及目标和十分相似

class Solution {
public:
    bool canPartition(vector<int>& nums) {
        //其实就是找一个集合值为特定值
        int sum = accumulate(nums.begin(),nums.end(),0);
        if(sum%2==1) return false;

        int target = sum/2;
        vector<bool> dp(target+ 1);
        dp[0] = 1;
        for (int& num : nums) {
            for (int j = target; j >= num; j--) {
                dp[j] =  dp[j]|dp[j - num];
                if(dp[target]==1) return true;//提前结束
            }
        }
        return dp[target];
}
};
posted @ 2022-07-06 23:49  失控D大白兔  阅读(21)  评论(0编辑  收藏  举报