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.code
Note:
Each of the array element will not exceed 100.
The array size will not exceed 200.
Example 1:element
Input: [1, 5, 11, 5]it
Output: trueio
Explanation: The array can be partitioned as [1, 5, 5] and [11].
Example 2:class
Input: [1, 2, 3, 5]动态规划
Output: falseco
Explanation: The array cannot be partitioned into equal sum subsets.new
1.解题思路
此问题属于动态规划中的背包问题。
背包问题:假设有n个宝石,只有一个容量为C的背包,且第i个宝石所对应的重量和价值为w[i]和v[i],求装哪些宝石能够得到最大的价值收益?
思路:咱们将n个宝石进行编号,0,1,2...n-1,寻找DP的状态和状态转移方程。咱们用dpij表示将前i个宝石装到剩余容量为j的背包中,那么久很容易获得状态转移方程了。(宝石从0开始编号,因此dpij是在考虑第i-1个宝石装包的状况,固然咱们要先初始化前0个宝石装包的状况,即dp0=0,由于不装任何宝石,因此不管如何价值都为0.)return
dp[i][j]=Math.max(dp[i-1][j],dp[i-1][j-w[i-1]]+v[i-1]) 背包没法再装下第i-1个宝石-> dp[i-1][j]; 继续将第i-1个宝石装包-> dp[i-1][j-w[i-1]]+v[i-1]。
搞清楚了背包问题,这个Partition Equal Subset Sum的题目就迎刃而解了。
1). 判断数组中全部数的和是否为偶数,由于奇数是不可能有解的;
2). 根据背包问题,取前i个数,体积为j的状况下,
dp[i][j]=Math.max(dp[i-1][j],dp[i-1][j-nums[i-1]]+nums[i-1])
3).若是最后dpnums.length=sum/2,则返回true.
2.代码
public class Solution { public boolean canPartition(int[] nums) { if(nums.length==0) return false; int sum=0; for(int n:nums){ sum+=n; } if(sum%2==1) return false; sum=sum/2; int[][] dp=new int[nums.length+1][sum+1]; for(int i=0;i<=nums.length;i++){ for(int j=0;j<=sum;j++){ if(i==0) //表示前0个数,因此价值均为0; dp[i][j]=0; //在装第i-1个数时,先判断剩余容量j是否大于nums[i-1] else if(j<nums[i-1]) dp[i][j]=dp[i-1][j]; //小于表示空间不够,因此维持不变 else{ //空间够,就经过比较大小来判断是否该放入第i-1个数 dp[i][j]=Math.max(dp[i-1][j],dp[i-1][j-nums[i-1]]+nums[i-1]); } } } return dp[nums.length][sum]==sum; } }