动态规划

分割等和子集

中等#416Java时间 O(n × 总和)空间 O(总和)

题目要做什么

判断正整数数组能否分成两个子集,使两部分的元素和相等。每个位置只能使用一次。

题目示例输入nums = [1,5,11,5]
题目示例输出true

01 为什么这样做

总和必须为偶数,问题转化为能否选出和为总和一半的子集。一维 0/1 背包从大到小更新,避免当前元素被重复使用。

始终成立的条件

处理当前数之前,dp 只表示用此前元素可达的和;倒序更新保持这个条件。

02 看见算法执行

动画与代码同步

修改输入,播放自己的例子

当前使用题目示例
修改输入会改变执行过程;预期输出用于核对结果。
数组 / nums步骤 1
执行状态
本次演示输出播放到最后查看

Solution.java参考解法
1class Solution {2    public boolean canPartition(int[] nums) {3        int total = 0;4        for (int x : nums) total += x;5        if (total % 2 != 0) return false;6        int target = total / 2;7        boolean[] dp = new boolean[target + 1];8        dp[0] = true;9        for (int x : nums) {10            for (int sum = target; sum >= x; sum--) {11                dp[sum] = dp[sum] || dp[sum - x];12            }13        }14        return dp[target];15    }16}

键盘控制:A 后退 · D 前进

编程练习

↑↓ 选择↵ 打开Pagefind 全文检索