题目明显可以转化为“是否存在和为sum/2的子数组”
所以就先求和,除以2,得出target sum
定义dp[i][s]
如果dp[i][s]=true, 表示nums[0, i]中存在一个subset的和为s
那么对于第i个数,能凑出s有两种情况:
1. 之前i-1个数已经能凑出s
2. 之前i-1的数能凑出s-num[i]
所以,dp[i][s] = dp[i-1][s] || dp[i-1][s-nums[i]];
然后就正常2D->1D空间优化,只需要存dp[s]
空间:O(maxSum)
时间:O(maxSum * n)
import java.util.*;
public class Solution {
public boolean partition (int[] nums) {
int sum = 0;
for (int n : nums) { sum += n; }
if ((sum & 1) == 1) return false; // odd
sum = sum >> 1; // sum/2
boolean[] dp = new boolean[sum+1];
dp[0] = true;
for (int n : nums) {
// short-circuit
if (dp[sum]) return true;
// loop backward to prevent dirty read
for (int s = sum; s > 0; s--) {
if (s - n >= 0)
dp[s] = dp[s] || dp[s-n];
}
}
return dp[sum];
}
}