题目连接:https://leetcode.com/problems/combination-sum-ii/description/数组
题目大意:与39题相似,只是这里数组中的数字能够有重复,且每个数字只能取一次。ide
法一:利用39题的剪枝代码,加了一个去重的操做(与前面47和90的去重操做同样)。代码以下(耗时27ms):spa
1 public List<List<Integer>> combinationSum2(int[] candidates, int target) { 2 List<List<Integer>> res = new ArrayList<List<Integer>>(); 3 List<Integer> tmp = new ArrayList<Integer>(); 4 Arrays.sort(candidates);//先进行排序 5 dfs(res, tmp, candidates, target, 0); 6 return res; 7 } 8 public static boolean dfs(List<List<Integer>> res, List<Integer> tmp, int[] candidates, int target, int start) { 9 if(target < 0) { 10 return false; 11 } 12 if(target == 0) {//递归结束条件 13 res.add(new ArrayList<Integer>(tmp)); 14 return false; 15 } 16 else {//这里必定要判断target>0,由于若是不判断就会致使target<0时还在往下递归 17 for(int i = start; i < candidates.length; i++) { 18 //去重 19 if(i > start && candidates[i] == candidates[i - 1]) { 20 continue; 21 } 22 tmp.add(candidates[i]); 23 boolean flag = dfs(res, tmp, candidates, target - candidates[i], i + 1);//这里是i,由于不能重复选 24 tmp.remove(tmp.size() - 1); 25 //剪枝,由于数组是排好序的,因此一旦总和<=0,那么其后的数字必定会致使当前结果<0,因此能够直接今后跳事后面的循环 26 if(flag == false) { 27 break; 28 } 29 } 30 } 31 return true; 32 }