40. 组合总和 II - 力扣(LeetCode) (leetcode-cn.com)
组合总和II
- DFS
- 回溯
- 去重
class Solution {
public:
vector<vector<int>> ans;
vector<int> path;
void DFS(vector<int>& candidates, int target, int sum, int index, vector<bool>& visited) {
if (sum > target) return;
if (sum == target) {
ans.emplace_back(path);
return;
}
for (int i = index; i < candidates.size(); ++i) {
// 产生重复的原因在于产生了相同的结果组,而不是某个数选了很多次
// 假设候选组为[1,2,1,5,1], 要产生和为9的组
// 那么有[1,2,1,5]和[1,2,5,1]以及[2,1,5,1]这3组答案产生
// 1,2组, 在第一个for循环时,选了两次1
// 1,3组, 在第二个for循环时,选了之前选过的1。
// 去重方法,先排序相邻方便比较去重
// 然后再用访问数组表示是否在同一层中,防止类似[1,1]这样不同层的相同数字会被if条件直接舍去
if (i > 0 && candidates[i] == candidates[i - 1] && visited[i - 1] == false) continue;
sum += candidates[i];
path.emplace_back(candidates[i]);
visited[i] = true;
DFS(candidates, target, sum, i+1, visited);
visited[i] = false;
sum -= candidates[i];
path.pop_back();
}
}
vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
vector<bool> visited(candidates.size(), false);
sort(candidates.begin(), candidates.end());
DFS(candidates, target, 0, 0, visited);
return ans;
}
};