本题有一个很直观的思路是直接用类似DFS
的解法,但是在leetcode上面超时了。
于是采用dynamic programming的解法:
核心逻辑:
partition[i][j] = (partition[i-1][j] || partition[i-1][j-nums[i]]);
i
这个维度是指截止到nums
array
的第i
个元素。j
是subset
的和partition[i][j]
是指截止到第i
个元素,是否能组成一个和为j
的subset
class Solution {
public:
bool canPartition(vector<int>& nums) {
int target = accumulate(nums.begin(), nums.end(), 0);
if (target % 2 != 0) {
return false;
}
target /= 2;
int sz = nums.size();
bool partition[sz][target+1];
for (int i = 0; i < sz; ++i) {
for (int j = 0; j <= target; ++j) {
partition[i][j] = false;
}
}
if (nums[0] <= target) {
partition[0][nums[0]] = true;
}
for (int i = 0; i < sz; ++i) {
partition[i][0] = true;
}
for (int i = 1; i < sz; ++i) {
for (int j = 1; j <= target; ++j) {
if (j >= nums[i]) {
partition[i][j] = (partition[i-1][j] || partition[i-1][j-nums[i]]);
}
else {
partition[i][j] = partition[i-1][j];
}
}
}
return partition[sz-1][target];
}
};
本题并不难,关键在于理解
nums
的总和并不会是一个很大的数,可以放心大胆地用dynamic programming