zoukankan      html  css  js  c++  java
  • 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];
        }
    }
    
  • 相关阅读:
    CF891E Lust
    Comet OJ 2019 夏季欢乐赛题解
    CF1098E Fedya the Potter
    CF1063F String Journey
    P4218 [CTSC2010]珠宝商
    AGC028 E
    51Nod 1584 加权约数和
    51Nod 1769 Clarke and math2
    Educational Codeforces Round 67
    斯特林数学习笔记
  • 原文地址:https://www.cnblogs.com/CodeSPA/p/13796480.html
Copyright © 2011-2022 走看看