算法训练营第四十二天|416. 分割等和子集

62 阅读1分钟

416. 分割等和子集

简单0-1背包

class Solution {
    public boolean canPartition(int[] nums) {
        int sum = 0;
        for(int num : nums){
            sum += num;
        }
        // base case
        if(sum % 2 != 0)return false;

        int target = sum / 2;

        // dp[i]: 重量为i的背包最多装下的物品价值
        // nums[i]: 物品的重量和价值
        int[] dp = new int[target + 1];

        for(int i = 0; i < nums.length; i++){
            for(int j = target; j >= nums[i]; j--){
                dp[j] = Math.max(dp[j], dp[j - nums[i]] + nums[i]);
            }

            // 剪枝,每一次完成内层的for-loop,检查是否等于目标值,优化时间复杂度
            if(dp[target] == target)return true;
        }

        return dp[target] == target;
    }
}

0-1背包压缩到一维时,外层遍历物品,内层遍历背包,且内从从后向前遍历以确保每件物品最多只被添加一次。