分割等和子集【动态规划】

  1. 分割等和子集
    给你一个 只包含正整数 的 非空 数组 nums 。请你判断是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。
    分割等和子集【动态规划】_第1张图片
class Solution {//test
    public boolean canPartition(int[] nums) {
        if(nums == null || nums.length == 0) return false;
        int n = nums.length;
        int sum = 0;
        for(int num : nums) {
            sum += num;
        }
        //总和为奇数,不能平分
        if(sum % 2 != 0) return false;
        int target = sum / 2;//分为两个等价的背包,只要验证其中一个能装满就可。剩下的自动满足。
        int[] dp = new int[target + 1];
        for(int i = 0; i < n; i++) {//遍历物品
            for(int j = target; j >= nums[i]; j--) {//倒序遍历背包,避免将前面的物品重复放入
                //物品 i 的重量是 nums[i],其价值也是 nums[i]
                dp[j] = Math.max(dp[j], dp[j - nums[i]] + nums[i]);
            }
           
            //剪枝一下,每一次完成內層的for-loop,立即檢查是否dp[target] == target,優化時間複雜度(26ms -> 20ms)
            if(dp[target] == target)
            //j表示背包默认总容量,放入物品后dp[j]表示背包总重量
                return true;
        }
        return dp[target] == target;
    }
}

你可能感兴趣的:(动态规划,算法)