416 Partition Equal Subset Sum
1. Question
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.
2. Implementation
(1) DP
思路: 如果nums可以被分成sum相等的两个subset,那么首先sum必须是偶数。接下来,我们要在nums数组里的n个数中,找到target sum/2是否存在,这是一个0/1背包问题。dp[i][j]表示nums里前i个数目中,是否存在sum是j。第一行代表没有任何数目,所以显然是false, 第一列代表target是0,这个表示空数组,任何数组都可以分成空数组和非空数组两部分,所以第一列初始化为true。接下来就是对于第i个数,如果它小于等于当前的sum j,只有两种操作: 选择i和不选择, 如果选择i的话,则dp[i][j] = dp[i - 1][j - nums[i]],不选择i的话,dp[i][j] = dp[i - 1][j].
class Solution {
public boolean canPartition(int[] nums) {
if (nums == null || nums.length <= 1) {
return false;
}
int sum = 0;
for (int num : nums) {
sum += num;
}
if (sum % 2 != 0) {
return false;
}
sum /= 2;
int n = nums.length;
boolean[][] dp = new boolean[n + 1][sum + 1];
for (int i = 0; i <= n; i++) {
for (int j = 0; j <= sum; j++) {
if (i == 0) {
dp[i][j] = false;
}
else if (j == 0) {
dp[i][j] = true;
}
else if (nums[i - 1] <= j) {
dp[i][j] = dp[i - 1][j] || dp[i - 1][j - nums[i - 1]];
}
else {
dp[i][j] = dp[i - 1][j];
}
}
}
return dp[n][sum];
}
}
3. Time & Space Complexity
时间复杂度O(n * sum), 空间复杂度O(n * sum)
Last updated
Was this helpful?