class Solution {
// 存储结果
List<List<Integer>> res = new ArrayList<>();
// 暂存
List<Integer> path = new ArrayList<>();
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
// 先对候选数组进行排序
Arrays.sort(candidates);
// 默认所有的元素均未被使用 赋值为false
boolean[] userd = new boolean[candidates.length];
backTracking(candidates,target,0,0,userd);
return res;
}
public void backTracking(int[] candidates,int target,int sum,int index,boolean[] userd){
if(sum > target){
return;
}
// 收集结果
if(sum == target){
res.add(new ArrayList<>(path));
return;
}
for(int i=index; i<candidates.length; i++){
/* 去重逻辑(关键)
如果当前遍历的元素与上一个元素相等,并且上一个元素没有被用过,此时需要进行去重:
例如数组为[1,1,2,...]
第一树枝:选择1(①)——>选择1(②)——>选择2
第二树枝:选择1(②)——>选择2 没有选择1(①) 需要把这种分支砍掉
势必会重复
*/
if(i>0 && candidates[i] == candidates[i-1] && userd[i-1]==false){
continue;
}
path.add(candidates[i]);
sum += candidates[i];
userd[i] = true;
// 递归
backTracking(candidates,target,sum,i+1,userd);
// 回溯
userd[i] = false;
sum -= candidates[i];
path.remove(path.size()-1);
}
}
}
运行结果: