39組合總和

題目描述

給定一個無重複元素的數組 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];
        }
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章