- 分割等和子集
给定一个只包含正整数的非空数组。是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。
注意:
每个数组中的元素不会超过 100
数组的大小不会超过 200
官网解法
class Solution {
public:
bool canPartition(vector<int>& nums) {
int n = nums.size();
if (n < 2) {
return false;
}
int sum = accumulate(nums.begin(), nums.end(), 0);
int maxNum = *max_element(nums.begin(), nums.end());
if (sum & 1) {
return false;
}
int target = sum / 2;
if (maxNum > target) {
return false;
}
vector<vector<int>> dp(n, vector<int>(target + 1, 0));
for (int i = 0; i < n; i++) {
dp[i][0] = true;
}
dp[0][nums[0]] = true;
for (int i = 1; i < n; i++) {
int num = nums[i];
for (int j = 1; j <= target; j++) {
if (j >= num) {
dp[i][j] = dp[i - 1][j] | dp[i - 1][j - num];
} else {
dp[i][j] = dp[i - 1][j];
}
}
}
return dp[n - 1][target];
}
};
DFS 为优化版,后续可以考虑加上优化,就是对于每个位置加上一个bool类型数组判断是否等于res
class Solution {
public:
bool flag = false;
void dfs(vector<int>& nums, int start, int res) {
if (res < 0) {
return ;
}
if (flag) {
return;
}
for (int i = start; i < nums.size(); i++) {
if (res == nums[i]) {
// cout << res << ends << nums[i] << endl;
flag = true;
return;
} else {
dfs(nums, i+1, res-nums[i]);
}
}
}
bool canPartition(vector<int>& nums) {
int sum = 0;
for (int num : nums) {
sum += num;
}
if (sum % 2) {
return false;
}
int add = sum / 2;
dfs(nums, 0, add);
return flag;
}
};