題目描述
給定一個無重複元素的數組 candidates 和一個目標數 target ,找出 candidates 中所有可以使數字和爲 target 的組合。
candidates 中的數字可以無限制重複被選取。
說明:
- 所有數字(包括 target)都是正整數。
- 解集不能包含重複的組合。
示例 1:
輸入: candidates = [2,3,6,7], target = 7,
所求解集爲:
[
[7],
[2,2,3]
]示例 2:
輸入: candidates = [2,3,5], target = 8,
所求解集爲:
[
[2,2,2,2],
[2,3,3],
[3,5]
]
思路分析
回溯問題。三要素。dfs+剪枝。
路徑:已經加入的數字。
選擇列表:還能選擇加入的數字。
結束條件:sum==target;sum > target。
這種寫法還能繼續優化,比如2,2,2,2 > 7,則後續的2223,2226,2227都可以不用進入函數,直接跳出。
代碼實現
public List<List<Integer>> combinationSum(int[] candidates, int target) {
List<List<Integer>> lists = new ArrayList<>();
if (candidates == null || candidates.length == 0) {
return lists;
}
if (candidates == null || candidates.length == 0 || target == 0) {
return lists;
}
process(candidates, target, lists, 0, new ArrayList<>(), 0);
return lists;
}
public void process(int[] candidates, int target, List<List<Integer>> lists, int sum, List<Integer> list, int i) {
if (sum > target || i > candidates.length - 1) {
return;
}
if (sum == target) {
lists.add(new ArrayList<>(list));
}
//這裏還能繼續優化,比如2222超出,後面就不用再繼續2223,2226,因爲必然超出
for (int j = i; j < candidates.length; j++) {
sum += candidates[j];
list.add(candidates[j]);
process(candidates, target, lists, sum, list, j);
list.remove(list.lastIndexOf(candidates[j]));
sum -= candidates[j];
}
}