可以看作是一个背包问题,当背包内的总和达到所有数总和的一半时,达到目标,状态转移方程为dp[i][j] = dp[i-1][j] | dp[i-1][sum/2-j]
考虑到若dp[i-1][j]为真,则dp[i][j]为真,可以将二维数组变成一维数组,此时需要从后向前循环。
class Solution {
public:
bool canPartition(vector<int>& nums) {
int sum = 0;
for (auto n:nums) sum += n;
if (sum%2) return false;
sum /= 2; //目标值
bool dp[sum+1];
for (int i = 1; i <= sum; i ++) dp[i] = false;
if (nums[0] < sum) dp[nums[0]] = true;
else if (nums[0] == sum) return true;
else return false;
for (int i = 1; i < nums.size(); i ++) {
int n = nums[i];
if (n == sum) return true;
else if (n > sum) return false;
//从后向前循环
for (int j = sum; j > n; j --) {
if (dp[j]) continue;
//状态转移
dp[j] = dp[j - n];
}
if (n < sum) dp[n] = true;
if (dp[sum]) return true;
}
return false;
}
};