原題連接在這裏:https://leetcode.com/problems/combination-sum/html
題目:post
Given a set of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T.url
The same repeated number may be chosen from C unlimited number of times.spa
Note:code
For example, given candidate set 2,3,6,7
and target 7
,
A solution set is: [7]
[2, 2, 3]
htm
題解:blog
本題與Combinations, Permutations, N-Queens都是backtracking.排序
dfs時, target減掉candidates裏一個數,而後遞歸調用helper, target設成target - candidates[i]. recursion終止條件是target == 0, 加入item的copy, target < 0說明已經減多了,直接return.遞歸
backtracking時恢復原貌.leetcode
題目中說要從小到大, 因此candidates的排序.
candidates裏可能有duplicate, 因此須要去重.
Time Complexity: exponential.
Space: O(size). res中最長item的size是recursion的stack space.
AC Java:
1 public class Solution { 2 public List<List<Integer>> combinationSum(int[] candidates, int target) { 3 List<List<Integer>> res = new ArrayList<List<Integer>>(); 4 if(candidates == null || candidates.length == 0){ 5 return res; 6 } 7 Arrays.sort(candidates); 8 helper(candidates, target, 0, new ArrayList<Integer>(), res); 9 return res; 10 } 11 12 private void helper(int[] candidates, int target, int start, List<Integer> item, List<List<Integer>> res){ 13 if(target == 0){ 14 //去重 15 if(!res.contains(item)){ 16 res.add(new ArrayList<Integer>(item)); 17 } 18 return; 19 } 20 if(target < 0){ 21 return; 22 } 23 24 for(int i = start; i<candidates.length; i++){ 25 item.add(candidates[i]); 26 helper(candidates, target-candidates[i], i, item, res); 27 item.remove(item.size()-1); 28 } 29 } 30 }
去重也能夠在循環中加入if(i>0 && candidates[i] == candidates[i-1]) continue; 是由於本題容許使用重複元素,若後面元素相同則不能再進行此驗算。而且起到了去重的做用,就不用眼看res中是否已有item了.
e.g. 如果candidates = [1,1,2], target 是 3, 則會返回多組 [1,1,1].
AC Java:
1 public class Solution { 2 public List<List<Integer>> combinationSum(int[] candidates, int target) { 3 List<List<Integer>> res = new ArrayList<List<Integer>>(); 4 if(candidates == null || candidates.length == 0){ 5 return res; 6 } 7 Arrays.sort(candidates); 8 helper(candidates,target,0,new ArrayList<Integer>(),res); 9 return res; 10 } 11 private void helper(int[] candidates, int target, int start, List<Integer> item, List<List<Integer>> res){ 12 if(target == 0){ 13 res.add(new ArrayList<Integer>(item)); 14 return; 15 } 16 if(target < 0){ 17 return; 18 } 19 for(int i = start; i<candidates.length; i++){ 20 //這裏能夠使用重複元素,因此如果下一個元素與以前元素相同則沒有必要對下一個元素進項判斷,浪費時間 21 if(i>start && candidates[i] == candidates[i-1]){ 22 continue; 23 } 24 item.add(candidates[i]); 25 helper(candidates,target-candidates[i],i,item,res); 26 item.remove(item.size()-1); 27 } 28 } 29 }
跟上Combination Sum II, Combination Sum III, Combination Sum IV.