LeetCode 416 分割等和子集

LeetCode 416 分割等和子集

问题描述:
给定一个只包含正整数的非空数组。是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。
注意:
每个数组中的元素不会超过 100
数组的大小不会超过 200

动态规划(0-1背包问题)

执行用时:21 ms, 在所有 Java 提交中击败了69.80%的用户
内存消耗:38.5 MB, 在所有 Java 提交中击败了58.03%的用户

class Solution {
    public boolean canPartition(int[] nums) {
        int n = nums.length;
        //边界条件
        if (n < 2) {
            return false;
        }
        int sum = 0, maxNum = 0;
        for (int num : nums) {
            sum += num;
            maxNum = Math.max(maxNum, num);
        }
        if (sum % 2 != 0) {
            return false;
        }
        int target = sum / 2;
        if (maxNum > target) {
            return false;
        }
        //递归过程
        //dp[i][j]表示数组中[0, i]范围是否能够选出和为j的子集
        //若nums[i]<=j,则dp[i][j] = dp[i-1][j] || dp[i][j-nums[i]]
        //若nums[i]>j,则dp[i][j] = dp[i-1][j]
        //初始状态dp[i][0] = true、dp[i][nums[i]] = true
        //由上可知dp[i][j]可能由dp[i-1][j]、dp[i-1][j-1]...dp[i-1][0]确定
        //因此可简化dp数组为boolean[] dp = new boolean[target+1]
        boolean[] dp = new boolean[target + 1];
        dp[0] = true;
        for (int i = 0; i < n; i++) {
            int num = nums[i];
            for (int j = target; j >= num; --j) {
                dp[j] |= dp[j - num];
            }
        }
        return dp[target];
    }
}
posted @ 2020-10-11 10:35  CodeSPA  阅读(95)  评论(0编辑  收藏  举报