Given a collection of candidate numbers (candidates) and a target number (target), find all unique combinations in candidates where the candidate numbers sums to target.
Each number in candidates may only be used once in the combination.
Note:
All numbers (including target) will be positive integers.
The solution set must not contain duplicate combinations.
给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的每个数字在每个组合中只能使用一次。
说明:
所有数字(包括目标数)都是正整数。
解集不能包含重复的组合。
Example 1:
Input: candidates = [10,1,2,7,6,1,5], target = 8,
A solution set is:
[
[1, 7],
[1, 2, 5],
[2, 6],
[1, 1, 6]
]
Example 2:
Input: candidates = [2,5,2,1,2], target = 5,
A solution set is:
[
[1,2,2],
[5]
]
思路:
和LeetCode 39. Combination Sum是镜像题目
思路几乎一样,在前者的基础上,本体需要改动的只有start = i + 1
,
并且新加一行auto it = find(res.begin(), res.end(), cur)
来保证去重。
C++
class Solution{
public:
vector<vector<int> > combinationSum2(vector<int>& candidates, int target){
sort(candidates.begin(),candidates.end());
vector<vector<int> > res;
vector<int > cur;
backtrack(candidates,target,res,cur,0);
return res;
}
private:
void backtrack(vector<int>& candidates, int target, vector<vector<int> >& res,vector<int >& cur, int start){
if(target == 0){//base case
auto it = find(res.begin(), res.end(), cur);//去重
if( it == res.end() ) res.push_back(cur);
return;
}
//decisions
for(int i = start; i < candidates.size() && target >= candidates[i]; i++){
cur.push_back( candidates[i] );
int newtarget = target - candidates[i];
start = i + 1;//start变成i + 1,每次都从start + 1开始,目的是去重
backtrack( candidates, newtarget, res, cur, start);
cur.pop_back();//回溯后没有得到正确解,回溯撤销
}
}
};