题意
题解
方法一:动态规划
dp[i][j]表示选取前i个元素,是否
class Solution {
public:
bool canPartition(vector<int>& nums) {
int sum = 0;
int n = nums.size();
for(int i = 0; i < nums.size(); i++)
sum += nums[i];
if (sum % 2) return false;
int target = sum / 2;
bool dp[n+1][target+1];
for (int i = 0; i <= n; i++)
for (int j = 0; j <= target; j++)
dp[i][j] = false;
dp[0][0] = true;
for (int i = 0; i <= n; i++)
dp[i][0] = true;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= target; j++) {
if (j >= nums[i-1]) {
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][target];
}
};
方法二:滚动数组优化
注意第二次遍历的方向
class Solution {
public:
bool canPartition(vector<int>& nums) {
int sum = 0;
int n = nums.size();
for(int i = 0; i < nums.size(); i++)
sum += nums[i];
if (sum % 2) return false;
int target = sum / 2;
bool dp[target+1];
for (int j = 0; j <= target; j++)
dp[j] = false;
dp[0] = true;
for (int i = 1; i <= n; i++) {
for (int j = target; j >= 1; j--)
if (j >= nums[i-1]) dp[j] = dp[j] || dp[j-nums[i-1]];
return dp[target];
}
};