1. 程式人生 > 其它 >39--組合總和(遞迴+回溯)

39--組合總和(遞迴+回溯)

題目

給你一個 無重複元素 的整數陣列 candidates 和一個目標整數 target ,找出 candidates 中可以使數字和為目標數 target 的 所有 不同組合 ,並以列表形式返回。你可以按 任意順序 返回這些組合。

candidates 中的 同一個 數字可以 無限制重複被選取 。如果至少一個數字的被選數量不同,則兩種組合是不同的。

對於給定的輸入,保證和為 target 的不同組合數少於 150 個。

示例 1:

輸入:candidates = [2,3,6,7], target = 7
輸出:[[2,2,3],[7]]
解釋:
2 和 3 可以形成一組候選,2 + 2 + 3 = 7 。注意 2 可以使用多次。
7 也是一個候選, 7 = 7 。
僅有這兩種組合。

連結:https://leetcode-cn.com/problems/combination-sum

解答

點選檢視程式碼
class Solution {
    public List<List<Integer>> combinationSum(int[] candidates, int target) {
        List<List<Integer>> ans = new ArrayList<List<Integer>>();
        List<Integer> combine = new ArrayList<Integer>();
        dfs(candidates, target, ans, combine, 0);
        return ans;
    }

    public void dfs(int[] candidates, int target, List<List<Integer>> ans, List<Integer> combine, int idx) {
        if (idx == candidates.length) {
            return;
        }
        if (target == 0) {
            ans.add(new ArrayList<Integer>(combine));
            return;
        }
        // 直接跳過
        dfs(candidates, target, ans, combine, idx + 1);
        // 選擇當前數
        if (target - candidates[idx] >= 0) {
            combine.add(candidates[idx]);
            dfs(candidates, target - candidates[idx], ans, combine, idx);
            combine.remove(combine.size() - 1);
        }
    }
}

理解

  • 首先第一次遞迴將陣列拉到最後一個位置,然後從最後一個位置開始,從後往前,每次都讓target減去陣列中的值,如果可以組合,那麼最終就會減到0.
    每次都會從這個位置開始,向後推進。
    其實就是用來target減去目標數。如果最後能在陣列中找出來組合成為0的就放入List中。