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:
- Each of the array element will not exceed 100.
- 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. 分析:https://leetcode.com/problems/partition-equal-subset-sum/discuss/90592/01-knapsack-detailed-explanation
This problem is essentially let us to find whether there are several numbers in a set which are able to sum to a specific value (in this problem, the value is sum/2).
Actually, this is a 0/1 knapsack problem, for each number, we can pick it or not. Let us assume dp[i][j] means whether the specific sum j can be gotten from the first i numbers. If we can pick such a series of numbers from 0-i whose sum is j, dp[i][j] is true, otherwise it is false.
Base case: dp[0][0] is true; (zero number consists of sum 0 is true)
Transition function: For ith number, if we don‘t pick it, dp[i][j] = dp[i-1][j], which means if the first i-1 elements has made it to j, dp[i][j] would also make it to j (we can just ignore nums[i]). If we pick nums[i]. dp[i][j] = dp[i-1][j-nums[i]], which represents that j is composed of the current value nums[i] and the remaining composed of other previous numbers. Thus, the transition function is dp[i][j] = dp[i-1][j] || dp[i-1][j-nums[i]]
1 class Solution { 2 public boolean canPartition(int[] nums) { 3 int sum = 0; 4 for (int num : nums) { 5 sum += num; 6 } 7 8 if ((sum & 1) == 1) { 9 return false; 10 } 11 sum /= 2; 12 13 int n = nums.length; 14 boolean[][] dp = new boolean[n + 1][sum + 1]; 15 16 dp[0][0] = true; 17 18 for (int i = 1; i < n + 1; i++) { 19 dp[i][0] = true; 20 } 21 for (int j = 1; j < sum + 1; j++) { 22 dp[0][j] = false; 23 } 24 25 for (int i = 1; i <= n; i++) { 26 for (int j = 1; j <= sum; j++) { 27 dp[i][j] = dp[i - 1][j]; 28 if (j >= nums[i - 1]) { 29 dp[i][j] = dp[i][j] || dp[i - 1][j - nums[i - 1]]; 30 } 31 } 32 } 33 34 return dp[n][sum]; 35 } 36 }
原文地址:https://www.cnblogs.com/beiyeqingteng/p/10817311.html