1 問題
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]
]
2 分析
如果對輸入不做處理,所有可能出現的數字組合有 target
比較,時間複雜度是指數級別的。
但是該問題蘊含着數字的大小、相等關係,因此需要利用這種內在的數字關係來提高算法的運行效率。
爲此,將輸入的數組進行排序,排序算法的時間複雜度是
設輸入的數組用 target
相等的組合,層數等於可能的組合中的數字個數。令
- 如果
Sn≤target 該節點存在子節點,繼續按照圖示規律訪問子節點; - 如果
Sn>target ,該節點爲葉子,應當回溯回父節點。
在所有可能的組合遍歷完成後,與target
相等的組合會被記錄下來。
該算法的時間複雜度爲樹中所有節點的數目,與題目所給輸入值有關。
3 代碼
遞歸+回溯:
public class Solution {
public List<List<Integer>> combinationSum(int[] candidates, int target) {
Arrays.sort(candidates);
List<List<Integer>> result = new ArrayList<List<Integer>>();
getResult(result, new ArrayList<Integer>(), candidates, target, 0);
return result;
}
private boolean getResult(List<List<Integer>> result, List<Integer> cur, int candidates[], int target, int start){
if(target == 0){
result.add(new ArrayList<Integer>(cur));
return true;
}else if(target < 0){
return false;
}else{
for(int i = start; i < candidates.length && target >= candidates[i]; i++){
cur.add(candidates[i]);
boolean res = getResult(result, cur, candidates, target - candidates[i], i);
if(!res){
return false;
}
cur.remove(cur.size() - 1);
}
return true;
}
}
}