LeetCode34动态规划背包问题● 416. 分割等和子集

该代码是解决背包问题的一个实例,使用动态规划方法检查整数数组是否能被分割成两个和相等的子集。首先计算数组的总和与最大值,如果总和为奇数或最大值大于总和的一半则返回false。然后使用一维数组dp进行动态规划,从后往前遍历,更新dp[j]的值。最后返回dp[sum/2]来判断是否能找到和为半数的子集。
摘要由CSDN通过智能技术生成

class Solution {
    public boolean canPartition(int[] nums) {
        //nums.sum % 2  != 0 return flase;
        //背包 sum / 2,物品 0 ~ i、
        //j > nums[i]
        //dp[i][j] = dp[i - 1][j] || dp[i - 1][j - nums[i]])  
        //j < nums[i]
        // dp[i][j] = dp[i - 1][j];
        //dp[i][0] = true,只要都不选就是0;dp[0][nums[0]] == true   dp的含义:0~i里面能选出来等于j。


        int max = 0;
        int sum = 0;
        for(int i : nums){
            sum += i;
            max = max > i ? max : i;
        }
        if(sum % 2 != 0)return false;
        if(max > sum / 2)return false;
        // //创建数组
        // boolean[][] dp = new boolean[nums.length][sum / 2 + 1];
        // //初始化
        // for(int i = 0;i < nums.length;i++){
        //     dp[i][0] = true;//不选就可以等于0
        // }
        // if(nums[0] <= sum / 2 )dp[0][nums[0]] = true;

        // //遍历
        // for(int i = 1;i < nums.length;i++){
        //     for(int j = 1;j <= sum / 2;j++){//背包大小 sum / 2
        //         // if(j == nums[i]){
        //         //    return true; 
        //         // }返回会错误  == j不代表等于sum / 2;
        //         if(j >= nums[i]){
        //             dp[i][j] = dp[i - 1][j] || dp[i - 1][j - nums[i]];
        //         }
        //         else  {
        //            dp[i][j] = dp[i - 1][j]; 
        //         }
        //     }
        // }
        // return dp[nums.length - 1][sum / 2];

         //nums.sum % 2  != 0 return flase;
        //背包 sum / 2,物品 0 ~ i、
        //dp[j]能装j的包可以有true不可以
        //j要从后往前遍历,先i后j
        //j > nums[i]
        //dp[j] = dp[j] || dp[j - nums[i]])  
        //j < nums[i]
        // dp[j] = dp[j];
        //dp[0] = true,只要都不选就是0;dp[nums[0]] == true   dp的含义:0~i里面能选出来等于j。

        //一维数组
        boolean[]dp = new boolean[sum / 2 + 1];
        dp[0] = true;
        if(nums[0] <= sum / 2 )dp[nums[0]] = true;
        for(int i = 1;i < nums.length;i++){
            for(int j = sum / 2;j > 1;j--){//背包大小 sum / 2
                // if(j == nums[i]){
                //    return true; 
                // }返回会错误  == j不代表等于sum / 2;
                if(j >= nums[i]){
                    dp[j] = dp[j] || dp[j - nums[i]];
                }
            }
        }
        return dp[sum / 2];
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值