LeetCode 39. Combination Sum

原題連接在這裏: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

  • All numbers (including target) will be positive integers.
  • Elements in a combination (a1, a2, … , ak) must be in non-descending order. (ie, a1 ≤ a2 ≤ … ≤ ak).
  • The solution set must not contain duplicate combinations. 

For example, given candidate set 2,3,6,7 and target 7
A solution set is: 
[7] 
[2, 2, 3] htm

題解:blog

本題與CombinationsPermutationsN-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 IICombination Sum IIICombination Sum IV.

相關文章
相關標籤/搜索