**给定一个候选人编号的集合 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合
candidates 中的每个数字在每个组合中只能使用 一次
注意:解集不能包含重复的组合 **
要3次剪枝的dfs题
class Solution {
List<List<Integer>> ans = new ArrayList<>();
List<Integer> list = new ArrayList<>();
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
boolean[] vis = new boolean[110];
Arrays.sort(candidates);//必须要排序
dfs(target,0,candidates,0,vis);
return ans;
}
public void dfs(int target,int sum,int[] candidates,int begin,boolean[] vis){
if(sum == target){//递归终点
ans.add(new ArrayList<>(list));
return;
}
if(sum > target){//若sum大于目标,return
return;
}
for(int i = begin;i<candidates.length;i++){//i = begin,dfs(i+1) 求组合,不看顺序
if(candidates[i] > target){//若排序后的数组值都大于目标,直接退出
break;
}
if(i > 0 && candidates[i] == candidates[i-1] && vis[i-1] == false){//若满足candidates[i] == candidates[i-1],并且vis[i-1]在一次递归执行到叶子节点后又置为了false,则说明这条递归得出的结果与上一条重复了,那么则跳过
continue;
}
if(vis[i] == false){
vis[i] = true;
list.add(candidates[i]);
dfs(target,sum+candidates[i],candidates,i+1,vis);//i+1是每个数字在每个组合中只能使用一次
list.remove(list.size()-1);
vis[i] = false;
}
}
}
}