• Leetcode 416. Partition Equal Subset Sum


    416. Partition Equal Subset Sum 

    Given a non-empty array containing only positive integers, find if the array can be partitioned into two subsets such that the sum of elements in both subsets is equal.

    Note:

    1. Each of the array element will not exceed 100.
    2. The array size will not exceed 200.

    Example 1:

    Input: [1, 5, 11, 5]
    
    Output: true
    
    Explanation: The array can be partitioned as [1, 5, 5] and [11].

    Example 2:

    Input: [1, 2, 3, 5]
    
    Output: false
    
    Explanation: The array cannot be partitioned into equal sum subsets.

    动态规划,0/1背包问题。对于输入的数组nums,首先nums中各个元素之和要是偶数,然后就是找到可以将nums中的元素划分为2个不相交子集,并且这2个子集互补。

    解法一:nums中的元素可以划分为2类:考虑了的和没考虑了的。由大值遍历到小值,具体可以根据代码画图理解。

     1 public class Solution {
     2     public boolean canPartition(int[] nums) {
     3         if (nums == null || nums.length == 0) {
     4             return false;
     5         }
     6         int sum = 0;
     7         for (int num : nums) sum += num;
     8         if (sum % 2 == 1) return false;
     9         sum /= 2;
    10         boolean[] dp = new boolean[sum + 1];//当前可以由考虑了的元素构成的值(每个元素最多出现1次)
    11         //0可以由给定的nuns数组的元素组成给出
    12         dp[0] = true;
    13         int curSum = 0;
    14         //nums中的元素可以划分为2类:考虑了的和没考虑了的
    15         for (int i = 0; i < nums.length; i++) {//一个一个元素按顺序加入考虑了的划分中,从而考虑全部可以构成的数的值
    16             int tmax = Math.min(curSum + nums[i], sum);//内循环的上限的有效值=min(当前考虑了的划分中的元素可以构成的最大的值,sum)
    17             for (int j = tmax; j >= nums[i]; j--) {
    18                 //构成j值只有2种情况:包含nums[i],不包含nums[i]
    19                 //包含nums[i]:dp[j] = dp[j - nums[i]]
    20                 //不包含nums[i]:dp[j] = dp[j] 
    21                 dp[j] = dp[j] || dp[j - nums[i]];
    22             }
    23             if (dp[sum]) return true;//一旦满足直接返回,减少遍历
    24             curSum += nums[i];
    25         }
    26         return dp[sum];
    27     }
    28 }

    解法二:

     1 public class Solution {
     2     public boolean canPartition(int[] nums) {
     3         int sum = 0;
     4         for (int num : nums) sum += num;
     5         if ((sum & 1) == 1) return false;//奇数还是偶数的判断
     6         sum /= 2;
     7         int n = nums.length;
     8         boolean[][] dp = new boolean[n + 1][sum + 1];//dp[i][j]=true表示的能够用前i个数的子集构成j值
     9         dp[0][0] = true;//用0个数构成0是true
    10         for (int i = 1; i <= n; i++) dp[i][0] = true;//用i个数的子集可以构成0
    11         for (int i = 1; i <= sum; i++) dp[0][i] = false;//用0个数不能构成大于0的任何数
    12         for (int i = 1; i <= n ; i++) {
    13             for (int j = 1; j <= sum; j++) {
    14                 //dp[i][j] = dp[i - 1][j] || dp[i - 1][j - nums[i - 1]]
    15                 //也是2种情况:
    16                 //包含nums[i - 1]:dp[i][j] = dp[i - 1][j]
    17                 //不包含nums[i - 1]:dp[i][j] = dp[i - 1][j - nums[i - 1]]
    18                 dp[i][j] = dp[i - 1][j];
    19                 if (j >= nums[i - 1]) dp[i][j] = dp[i][j] || dp[i - 1][j - nums[i - 1]];
    20             }
    21         }
    22         return dp[n][sum];
    23     }
    24 }
  • 相关阅读:
    【大数据应用技术】作业十二|Hadoop综合大作业
    【大数据应用技术】作业十一|分布式并行计算MapReduce
    【大数据应用技术】作业十|分布式文件系统HDFS 练习
    【大数据应用技术】作业九|安装关系型数据库MySQL 安装大数据处理框架Hadoop
    【大数据应用技术】作业八|爬虫综合大作业(上)
    【大数据应用技术】作业七|爬取全部的校园新闻
    【大数据应用技术】作业六|获取一篇新闻的全部信息
    【大数据应用技术】作业五|理解爬虫原理
    【大数据应用技术】作业四|中文词频统计
    大数据应用期末总作业
  • 原文地址:https://www.cnblogs.com/Deribs4/p/6358008.html
Copyright © 2020-2023  润新知