题目描述
给你一个 只包含正整数 的 非空 数组 nums 。请你判断是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。
题解
由题可知,数组nums
非空,所以分割后的两个子集也必然非空,由于都是正整数,所以nums
中元素之和必然为偶数。
这道题是典型的 01 背包问题,假设$dp[i][j]$表示nums
中前$i$个元素是否包含和为$j$的子集,那么:
- 当
nums[i] = j
的时候,dp[i][j] = true
- 当
nums[i] > j
的时候,dp[i][j] = dp[i - 1][j]
- 当
nums[i] < j
的时候,dp[i][j] = dp[i - 1][j] || dp[i - 1][j - nums[i]]
#include <vector>
#include <numeric>
class Solution {
public:
bool canPartition(const std::vector<int>& nums) {
int size = nums.size();
int sum = std::accumulate(nums.begin(), nums.end(), 0);
if (size == 1 || (sum & 1) == 1) return false;
int target = sum / 2;
std::vector<std::vector<bool>> dp(size + 1, std::vector<bool>(target + 1));
for (int i = 1; i <= size; ++i) {
for (int j = 1; j <= target; ++j) {
int num = nums[i - 1];
if (num == j) dp[i][j] = true;
else if (num > j) dp[i][j] = dp[i - 1][j];
else dp[i][j] = dp[i - 1][j] | dp[i - 1][j - num];
}
}
return dp[size][target];
}
};
评论