博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Leetcode 416. Partition Equal Subset Sum
阅读量:4649 次
发布时间:2019-06-09

本文共 2842 字,大约阅读时间需要 9 分钟。

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: trueExplanation: The array can be partitioned as [1, 5, 5] and [11].

 

Example 2:

Input: [1, 2, 3, 5]Output: falseExplanation: 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是true10         for (int i = 1; i <= n; i++) dp[i][0] = true;//用i个数的子集可以构成011         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 }

 

转载于:https://www.cnblogs.com/Deribs4/p/6358008.html

你可能感兴趣的文章
mechanize (1)
查看>>
FactoryBean
查看>>
Coolite动态加载CheckboxGroup,无法在后台中获取
查看>>
如何在我们项目中利用开源的图表(js chart)
查看>>
nfs服务器工作原理
查看>>
C3P0连接池工具类使用
查看>>
SVN常用命令备注
查看>>
孩子教育
查看>>
解决Cacti监控图像断断续续问题
查看>>
结构体的传参理解成员的存储方式
查看>>
python 进程与线程(理论部分)
查看>>
什么是API
查看>>
Java反射中method.isBridge() 桥接方法
查看>>
[shiro学习笔记]第二节 shiro与web融合实现一个简单的授权认证
查看>>
强名称程序集(strong name assembly)——为程序集赋予强名称
查看>>
1028. List Sorting (25)
查看>>
BZOJ 1613: [Usaco2007 Jan]Running贝茜的晨练计划
查看>>
ubuntu 重启命令,ubuntu 重启网卡方法
查看>>
Linux的学习:
查看>>
JavaScript中的原型继承原理
查看>>