力扣【416. 分割等和子集】详细Java题解(背包问题)

首先我们可以求出数组和,当我们找到一个子集中元素的和为数组和的一半 时,该就说明可以分割等和子集。

对于该问题我们可以转换成背包问题,求 数组里的元素 装入 数组和的一半大小的背包 能取得的最大值。

然后注意可以剪枝的地方。

代码:

csharp 复制代码
class Solution {
    public boolean canPartition(int[] nums) {
        //计算数组的和
        int sum =0;
        for(int num:nums) sum += num;
        if(sum%2 != 0) return false; //如果和为奇数,那就不符合
        sum /= 2;
        int[][] dp = new int[nums.length+1][sum+1]; //dp[i][j]表示遍历到前i个物品时,j容量背包能转的最大值
        //第0行就是还没有物品加入计算,初始化为0
        for(int i=0;i<sum+1;i++){
            dp[0][i] = 0; 
        }
        //开始动规计算
        for(int i=1;i<=nums.length;i++){
            for(int j=1;j<=sum;j++){
                if(nums[i-1] <= j) dp[i][j] = Math.max(nums[i-1] + dp[i-1][j-nums[i-1]],dp[i-1][j]);
                else dp[i][j] = dp[i-1][j];
            }
            if(dp[i][sum] == sum) return true; //剪枝
        }
        //结果判断
        if(dp[nums.length][sum] == sum){
            return true;
        }
        return false;
    }
}

不过我们其实可以用一维数组来做,因为我们的每次迭代其实只用到了dp数组的上一行。那我们可以用一个数组来进行滚动,不过遍历顺序得从后往前,因为我们迭代后面的物品时需要用到前面物品的值,且当容量大于当前遍历的物品时才迭代。

这样我们的代码更简洁且时间复杂度和空间复杂度都有改善。

csharp 复制代码
class Solution {
    public boolean canPartition(int[] nums) {
        //计算数组的和
        int sum =0;
        for(int num:nums) sum += num;
        if(sum%2 != 0) return false; //如果和为奇数,那就不符合
        sum /= 2;
        int[] dp = new int[sum+1]; 
        //第0行就是还没有物品加入计算,初始化为0
        for(int i=0;i<sum+1;i++){
            dp[i] = 0; 
        }
        //开始动规计算
        for(int i=1;i<=nums.length;i++){
            for(int j=sum;j>=nums[i-1];j--){
                dp[j] = Math.max(nums[i-1] + dp[j-nums[i-1]],dp[j]);
                if(j==sum && dp[j] == sum) return true; //剪枝
            }
        }
        return false;
    }
}
相关推荐
李老师讲编程11 小时前
中国电子学会图形化2020.12月Scratch三级考级题
算法·scratch·信息学奥赛·图形化编程·scratch素材
华如锦12 小时前
面了很多 Java转AI Agent方向,一些面试题总结
java·开发语言·人工智能·python·ai
睡不醒男孩03082312 小时前
CLup 6.x 版本中针对StarRocks 存算一体集群的完整操作手册
java·服务器·网络·clup
退休倒计时12 小时前
【每日一题】LeetCode 53. 最大子数组和 TypeScript
数据结构·算法·leetcode·typescript
旖-旎12 小时前
FloodFill(图像渲染)(1)
c++·算法·深度优先·力扣
戴西软件12 小时前
戴西 DLM 许可授权管理系统:破解无网络环境下工业软件授权难题,助力制造企业降本增效
网络·人工智能·python·深度学习·程序人生·算法·制造
2601_9618752412 小时前
法考资料2026|全套|资料已整理
数据结构·算法·链表·贪心算法·eclipse·线性回归·动态规划
无限码力12 小时前
美团研发岗 4月18号笔试真题 - 坐标
算法·美团笔试真题·美团笔试题·美团研发岗笔试题·美团研发岗4月18号真题
程序员黑豆12 小时前
Java中怎么实现字符串拼接呢【AI全栈开发】
java