dfs。注意各种剪枝即可。
bool myComp(vector<int>& a, vector<int>& b) {
for (int i = 0; i < min(a.size(), b.size()); i++) {
if (a[i] < b[i]) {
return true;
}
if (a[i] > b[i]) {
return false;
}
}
return false;
}
class Solution {
public:
vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
vector<vector<int>> ret;
vector<int> c;
int sum = 0;
sort(candidates.begin(), candidates.end());
for (int i = 0; i < candidates.size(); i++) {
if (candidates[i] <= target) {
if (i > target) {
if (candidates[i - target] == candidates[i]) {
continue;
}
}
c.push_back(candidates[i]);
sum += candidates[i];
}
}
sort(c.begin(), c.end());
vector<int> arr;
dfs(c, 0, target, sum, arr, ret);
vector<vector<int>> ans;
if (ret.size()) {
sort(ret.begin(), ret.end(), myComp);
ans.push_back(ret[0]);
for (int i = 1; i < ret.size(); i++) {
vector<int>& a = ret[i - 1];
vector<int>& b = ret[i];
if (!isEqual(a, b)) {
ans.push_back(b);
}
}
}
return ans;
}
void dfs(vector<int>& c, int idx, int target, int sum, vector<int>& arr, vector<vector<int>>& ret) {
if (idx >= c.size() || target <= 0 || sum < target) {
return;
}
if (target < c[idx]) {
return;
}
if (target == c[idx]) {
arr.push_back(c[idx]);
if (ret.empty() || !isEqual(arr, ret[ret.size() - 1])) {
ret.push_back(arr);
}
arr.pop_back();
return;
}
dfs(c, idx + 1, target, sum - c[idx], arr, ret);
arr.push_back(c[idx]);
dfs(c, idx + 1, target - c[idx], sum - c[idx], arr, ret);
arr.pop_back();
}
bool isEqual(vector<int>& a, vector<int>& b) {
if (a.size() != b.size()) {
return false;
}
for (int i = 0; i < a.size(); i++) {
if (a[i] != b[i]) return false;
}
return true;
}
};