LeetCode 39. Combination Sum (組合的和)


Given a set of candidate numbers (C) (without duplicates) and a target number (T), find all unique combinations in C where the candidate numbers sums to T.

The same repeated number may be chosen from C unlimited number of times.

Note:

  • All numbers (including target) will be positive integers.
  • 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]
]

 

 


題目標簽:Array

  題目給了我們一個candidates array 和一個 target, 讓我們從array 里找到所有的組合,它的和是等於target的。任何組合只要是它的和等於target的話,都需要找到,但是不需要重復的。這道題中是可以重復利用一個數字的,那么我們就需要每次都代入同一個數字,直到它之和達到target 或者它超過了target, 然后在倒退回去一個數字,繼續找下一個數字,這種情況肯定是要用遞歸了。這里是backtracking,每次倒退回一個數字,需要繼續遞歸下去,在倒退,一直重復直到搜索了所有的可能性。

  我們可以看原題中的例子:

  [2,3,6,7]  target 7

  2                                  選2,sum = 2

  2+2                              選2,sum = 4

  2+2+2                          選2,sum = 6

  2+2+2+2                      選2,sum = 8 這時候 sum已經超出target,需要返回到上一個數字

  2+2+2+3                      選3,sum = 9, 也超出了target, 這里我們可以發現,如果是sorted array的話,從小到大,只要一次超出,后面的數字必然也會超出target,所以可以在第一次超出的時候就直接跳出這一個迭代

  2+2+3                          選3,sum = 7,等於target, 此時返回並且跳出這一個迭代,因為后面的數字肯定超出(array里不會有重復的數字)

  2+3                              選3,sum = 5,小於target,繼續遞歸同一個數字

  2+3+3                          選3,sum = 8,超出target,返回上一個數字

  2+6                              選6,sum = 8,超出target,返回上一個數字

  3                                  選3,這里繼續從3開始遞歸

  ...

  ...

  ...

  我們可以看出,一開始有一個迭代從2,一直到7,然后把每一個數字遞歸下去,包括它自己,每次遞歸下去的數字,會繼續有一個迭代,一旦超出或者等於了,返回前面一個數字繼續遞歸。所以把array sort一下就可以提早跳出那一輪的迭代。

 

具體看下面代碼。

 

Java Solution:

Runtime beats 97.14% 

完成日期:07/16/2017

關鍵詞:Array

關鍵點:Backtracking with sorted array

 

 1 public class Solution 
 2 {
 3     public List<List<Integer>> combinationSum(int[] candidates, int target) 
 4     {
 5         List<List<Integer>> list = new ArrayList<>();
 6         Arrays.sort(candidates);
 7         backtrack(list, new ArrayList<>(), candidates, target, 0);
 8         
 9         return list;
10     }
11     
12     public static boolean backtrack(List<List<Integer>> list, List<Integer> tempList, int[] nums, int remain, int start)
13     {
14         if(remain < 0) // if remain is 0 or less than 0, meaning the rest numbers are even greater
15             return false; // therefore, no need to continue the loop, return false
16         else if(remain == 0)
17         {
18             list.add(new ArrayList<>(tempList));
19             return false;
20         }
21         else
22         {
23             for(int i=start; i<nums.length; i++)
24             {
25                 boolean flag;
26                 tempList.add(nums[i]);
27                 flag = backtrack(list, tempList, nums, remain - nums[i], i); // not i + 1 because we can use same number.
28                 tempList.remove(tempList.size() - 1);
29                 
30                 if(!flag) // if find a sum or fail to find a sum, there is no need to continue
31                     break;// because it is a sorted array with no duplicates, the rest numbers are even greater.
32             }
33             
34             return true; // return true because previous tempList didn't find a sum or fail a sum
35         }
36     }
37 }

參考資料:

https://leetcode.com/problems/combination-sum/#/discuss

 

LeetCode 算法題目列表 - LeetCode Algorithms Questions List

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM