题目:
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.
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 组合总和 (C++/Java)的扩展,我们还是利用39题中的方法来做这道题。
只不过本题所给的数字有重复,且要求最后的结果中不能有重复的,例如例子1,有两个1,他们都可以和7组合成8,如果按照39题搜索的方法就会产生重复结果。
其中一个办法就是将搜索生成的结果加入到set中,这样集合类会自动帮我们去重。
此外我们还可以在每一轮搜索时,当发现有相同元素时,直接跳过本次搜素,这样就不会产生重复的结果了。
程序:
C++
class Solution { public: vector<vector<int>> combinationSum2(vector<int>& candidates, int target) { vector<vector<int>> res; vector<int> curr; sort(candidates.begin(), candidates.end()); dfs(candidates, target, 0, res, curr); return res; } void dfs(vector<int>& candidates, int target, int index, vector<vector<int>>& res, vector<int> curr){ if(target == 0){ res.push_back(curr); return; } for(int i = index; i < candidates.size(); ++i){ if(candidates[i] > target) return; if(i > index && candidates[i] == candidates[i-1]) continue; curr.push_back(candidates[i]); dfs(candidates, target-candidates[i], i+1, res, curr); curr.pop_back(); } } };
Java
class Solution { public List<List<Integer>> combinationSum2(int[] candidates, int target) { List<List<Integer>> res = new ArrayList<>(); LinkedList<Integer> curr = new LinkedList<>(); Arrays.sort(candidates); dfs(candidates, target, 0, res, curr); return res; } private void dfs(int[] candidates, int target, int index, List<List<Integer>> res, LinkedList<Integer> curr){ if(target == 0){ res.add(new LinkedList<>(curr)); return; } for(int i = index; i < candidates.length; ++i){ if(candidates[i] > target) return; if(i > index && candidates[i] == candidates[i-1]) continue; curr.addLast(candidates[i]); dfs(candidates, target-candidates[i], i+1, res, curr); curr.removeLast(); } } }