和去重有关的回溯就可以算得上好题
这里的去重比前几个难一点,不要用set效率太低了。还是先排序,我们要的是在当前层不能取相同的数字,而在下一层还是可以取的,所以和排列的简单的和前面比较不同。要在i>index的情况下和前面比,如果i==index,那么不管前面是什么,当前层是第一次取这个数字是没关系的。
i>index这个条件很重要
class Solution {
public:
void dfs(vector<int>& candidates, int target, int index){
if(target == 0){
res.push_back(tmp);
return;
}
if(target < 0) return;
for(int i = index; i < candidates.size(); ++i){
//不是排列是组合,更简单
//还是会有重复的,比如将两个1作为最前面,那么125和125就重复了,所以在同一层不能选相同的数字
//虽然在当前这层不能用,但是下一层是能用的比如116
if(i > index && candidates[i] == candidates[i-1]) continue;
tmp.push_back(candidates[i]);
dfs(candidates,target-candidates[i],i+1);
tmp.pop_back();
}
}
vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
//dfs加回溯,防止重复,先排序,然后判断在同一层判断当前数字和前一个字符是否相等
sort(candidates.begin(),candidates.end());
dfs(candidates,target,0);
return res;
}
private:
vector<vector<int>> res;
vector<int> tmp;
};