给定一个候选人编号的集合?candidates
?和一个目标数?target
?,找出?candidates
?中所有可以使数字和为?target
?的组合。
candidates
?中的每个数字在每个组合中只能使用?一次?。
注意:解集不能包含重复的组合。?
示例?1:
输入: candidates =?[10,1,2,7,6,1,5], target =?8, 输出: [ [1,1,6], [1,2,5], [1,7], [2,6] ]
示例?2:
输入: candidates =?[2,5,2,1,2], target =?5, 输出: [ [1,2,2], [5] ]
提示:
1 <=?candidates.length <= 100
1 <=?candidates[i] <= 50
1 <= target <= 30
思路:和39一样的思路,注意回溯
class Solution {
List<List<Integer>> result = new ArrayList<>();
LinkedList<Integer> path = new LinkedList<>();
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
if (candidates == null || candidates.length == 0){
return result;
}
Arrays.sort(candidates);
backTrachking(candidates,target,0);
return result;
}
public void backTrachking(int[] candidates,int target,int index){
//终止条件
if (target == 0){
result.add(new ArrayList<>(path));
return;
}
if (target < 0){
return;
}
if (index == candidates.length){
return;
}
for (int i = index; i < candidates.length; i++) {
//正确剔除重复解的办法
//跳过同一树层使用过的元素
if ( i > index && candidates[i] == candidates[i - 1] ) {
continue;
}
int curNum = candidates[i];
if (target - curNum < 0){
break;
}
path.add(curNum);
backTrachking(candidates,target - curNum,i + 1);//这里加一是不能重复使用
path.removeLast();
}
}
}