原题连接在这里: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.