题链40.组合总和II
给定一个候选人编号的集合 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的每个数字在每个组合中只能使用 一次 。
**注意:解集不能包含重复的组合。 **
示例 1:
输入: candidates = [10,1,2,7,6,1,5], target = 8,
输出:
[
[1,1,6],
[1,2,5],
[1,7],
[2,6]
]
示例 2:
输入: candidates = [2,5,2,1,2], target = 5,
输出:
[
[1,2,2],
[5]
]
本题是一道较综合的题
主体为: 回溯 + 去重
以下给出两种去重思路:
1. used数组
首先将candidates进行排序方便去重
以candidates=[1,1,1,2,4],target=7为例
从第一个1开始:第一组结果[1,1,1,4] 第二组结果[1,2,4]
而从第二个1开始,便会有[1,2,4]的重复
以此,对于连续的数字,我们只需取第一个即可,后面的相同数字需跳过
我们用一个used数组来进行去重:
当当前数与前数相同时,若前数未选中,那么它就不是第一个该数,应当被跳过
在回溯前将本位used设为true,回溯后改回false即可
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| class Solution { private: vector<vector<int>> res; vector<int> path, candidates; void backtracking(int target, int idx, vector<bool> &used) { if (target < 0) return; if (target == 0) { res.emplace_back(path); return; } for (int i = idx; i < candidates.size(); i++) { if (i > 0 && candidates[i] == candidates[i-1] && used[i-1] == false) continue; int cur = candidates[i]; path.emplace_back(cur); used[i] = true; backtracking(target - cur, i + 1, used); used[i] = false; path.pop_back(); } } public: vector<vector<int>> combinationSum2(vector<int>& _candidates, int target) { res.clear(); path.clear(); candidates = _candidates; sort(candidates.begin(), candidates.end()); vector<bool> used(candidates.size(), false); backtracking(target, 0, used); return res; } };
|
2.startIndex
直接将传入的index作为连续数中的第一个
在for循环中只选取连续数中的第一个数
其中的if (i > idx && candidates[i] == candidates[i-1]) continue;判断注意顺序
否则会出现越界访问
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| class Solution { private: vector<vector<int>> res; vector<int> path, candidates; void backtracking(int target, int idx) { if (target < 0) return; if (target == 0) { res.emplace_back(path); return; } for (int i = idx; i < candidates.size(); i++) { if (i > idx && candidates[i] == candidates[i-1]) continue; int cur = candidates[i]; path.emplace_back(cur); backtracking(target - cur, i + 1); path.pop_back(); } } public: vector<vector<int>> combinationSum2(vector<int>& _candidates, int target) { res.clear(); path.clear(); candidates = _candidates; sort(candidates.begin(), candidates.end()); backtracking(target, 0); return res; } };
|