题目链接
分析
首先求数组和,对于数组和为奇数的情况无法分割。
数组和为偶数的情况下,为01背包问题
设 $dp[i][j]$ 为前 $i$ 个数是否可以凑出和为 $j$ 的子集
状态转移方程为 $dp[i][j] = dp[i - 1][j] \ dp[i][j - nums[i]]$
答案为 $dp[x]$ ,$x$ 为数组之和的一半
代码实现
class Solution {
public:
bool canPartition(vector<int>& nums) {
int sum = accumulate(nums.begin(), nums.end(), 0);
if(sum & 1)
return false;
int h = sum >> 1;
vector<int> dp(h + 1, false);
dp[0] = true;
for(int i = 0; i < nums.size(); ++i) {
for(int j = h; j >= nums[i]; --j) {
dp[j] |= dp[j - nums[i]];
}
}
return dp[h];
}
};
复杂度分析
- 时间复杂度:$O(n^2)$
- 空间复杂度:$O(n)$