题目
Given a collection of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T.
Each number in C may only be used once in the combination.
Note:
All numbers (including target) will be positive integers.
Elements in a combination (a1, a2, … , ak) must be in non-descending order. (ie, a1 ≤ a2 ≤ … ≤ ak).
The solution set must not contain duplicate combinations.
For example, given candidate set 10,1,2,7,6,1,5 and target 8,
A solution set is:
[1, 7]
[1, 2, 5]
[2, 6]
[1, 1, 6]
思路
思路与上篇博文思路一样,只是在最后加上了一个”去重“操作。去重操作借助于HashSet来完成。
实现代码如下:
public class Solution {
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
if(candidates==null||candidates.length<1){
return null;
}
Arrays.sort(candidates);
List<List<Integer>> result =combination(candidates,target,0);
//对返回的List<Integer>进行一个去重处理
Set<List<Integer>> set=new HashSet<List<Integer>>();
for(List<Integer> l:result){
set.add(l);
}
result.clear();
for(List<Integer> l:set){
result.add(l);
}
return result;
}
private List<List<Integer>> combination(int[] candidates, int target, int start) {
if(candidates==null||candidates.length<1){
return null;
}
List<List<Integer>> result=new ArrayList<List<Integer>>();
for(int i=start;i<candidates.length;i++){
if(candidates[i]<target){
for(List<Integer> res:combination(candidates,target-candidates[i],i+1)){
res.add(0, candidates[i]);
result.add(res);
}
}
else if(candidates[i]==target){
List<Integer> l=new ArrayList<Integer>();
l.add(candidates[i]);
result.add(l);
return result;
}
else{
break;
}
}
return result;
}
}
遇到的问题
1、没有考虑结果的重复性。上篇博文中是不需要考虑重复性,因为每个数可以取无限次。
解决的方法:在最后的结果中借用容器Set来过滤即可。
代码如下:
List<List<Integer>> result =combination(candidates,target,0);
//对返回的List<Integer>进行一个去重处理
Set<List<Integer>> set=new HashSet<List<Integer>>();
for(List<Integer> l:result){
set.add(l);
}
result.clear();
for(List<Integer> l:set){
result.add(l);
}
最后的AC结果如下:
小结
此题与上一题:Combination Sum思路一模一样,只是要考虑一个重复的问题。