Leetcode 40 組合總和 II
阿新 • • 發佈:2018-11-10
題目
給定一個數組 candidates 和一個目標數 target ,找出 candidates 中所有可以使數字和為 target 的組合。
candidates 中的每個數字在每個組合中只能使用一次。
說明:
所有數字(包括目標數)都是正整數。
解集不能包含重複的組合。
示例 1: 輸入: candidates = [10,1,2,7,6,1,5], target = 8, 所求解集為: [ [1, 7], [1, 2, 5], [2, 6], [1, 1, 6] ] 示例 2: 輸入: candidates = [2,5,2,1,2], target = 5, 所求解集為: [ [1,2,2], [5] ]
思路
和39題一樣,也是利用遞迴的方法,只要總和<target就繼續新增下一個數,且用start來標記下一個數的陣列下標。在一開始先對陣列c進行一次排序,這樣在新增到結果res中時,通過res.contains()即可判斷是否重複。
public int min = 10000000; public int sum = 0; public List<List<Integer>> res = new ArrayList<>(); public List<List<Integer>> combinationSum2(int[] c, int target) {//c:無重複元素的陣列 res.clear(); sum = 0 ; Arrays.sort(c);//排序 min = c[0]; List<Integer> tmp = new ArrayList<>(); recycle22(c, tmp, target, 0); return res; } //和39題一樣,也是利用遞迴的方法,只要總和<target就繼續新增下一個數,且用start來標記下一個數的陣列下標。 //在一開始先對陣列c進行一次排序,這樣在新增到結果res中時,通過res.contains()即可判斷是否重複 public void recycle22(int[] c, List<Integer> list, int tar, int start) {//用start表示能使用的元素的下標,防止一個元素被重複使用 if(sum == tar) { if(!res.contains(list)) //list已經是有序的了,所以通過res.contains()即可去掉重複的 res.add(new ArrayList<Integer>(list)); return ; } for(int i = start; i < c.length; i++) { if(sum + c[i] <= tar) { list.add(c[i]); sum += c[i]; recycle22(c, list, tar, i+1);//遞迴 sum -= c[i];//回溯,即回到上一個狀態 list.remove(list.size() - 1); } } }
執行時間約為40~50ms,leetcode戰勝30%左右,估計還有時間更少的解法,但對我來說這可能是一種比較