这道题目就是在上一道题目的基础之上进行的改动,不允许combination中出现重复的元素。
在上一道题目中,对数组进行排序是不必要的,但是这道题目是必要的,因为题目接下来需要使用数组排序的这个性质跳过重复的元素,跳过的方法很有技巧性: if(i > start && candidates[i] == candidates[i - 1]:
比如说对于1 1 2 5 6 7 10; 8,当第一个1调用的时候,会产生一个答案1 2 5,这时这条语句会跳过下一个从1开始调用的情况,从而达到避免重复的目的,代码如下:
public class Solution {
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
List<List<Integer>> list = new ArrayList<List<Integer>>();
Arrays.sort(candidates);
backtrack(list, new ArrayList<Integer>(), candidates, target, 0);
return list;
}
private void backtrack(List<List<Integer>> list, ArrayList<Integer> solution, int[] candidates, int remain, int start){
if(remain < 0) return;
if(remain == 0){
list.add(new ArrayList<>(solution));
return;
}
for(int i = start; i < candidates.length; i++){
if(i > start && candidates[i] == candidates[i - 1]) continue; // jump duplicate numbers
solution.add(candidates[i]);
backtrack(list, solution, candidates, remain - candidates[i], i + 1);
solution.remove(solution.size() - 1);
}
}
}