原题链接
解题思路
回溯剪枝。注意点就是两个相同的list处理。方法是先排序,这样相同的数字就紧挨着,当数字等于上一个数字时,表明上个同样的数字已经处理过,这个没必要再处理,continue就可以了。
其他的就看代码吧。
解题代码
public class Solution {
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
List<List<Integer>> res = new ArrayList<List<Integer>>();
Arrays.sort(candidates);
select(candidates,0,0,target,res,new ArrayList<Integer>());
return res;
}
public void select(int[] candidates,int sum, int idx,int target,List<List<Integer>> res,List<Integer> list) {
if(sum == target) {
res.add(new ArrayList<>(list));//一定要新建一个list,原来的list会被剪枝清空。
return;
}
for (int i = idx;i < candidates.length ;i++ ) {
if (i > idx && candidates[i] == candidates[i-1]) {
continue;
}
if(sum + candidates[i] <= target) {
list.add(candidates[i]);
select(candidates,sum + candidates[i],i+1,target,res,list);
list.remove(list.size()-1);//剪枝
}
}
}
}