1. 程式人生 > 實用技巧 >LeetCode-39-組合總數

LeetCode-39-組合總數

LeetCode-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]
]

提示:

1 <= candidates.length <= 30
1 <= candidates[i] <= 200
candidate 中的每個元素都是獨一無二的。
1 <= target <= 500

思路

一開始以為用動態規劃,後來發現需要求的是所有,那麼就屬於搜尋問題了;

我的思路是用dfs來做,做一個路徑來記錄選取的數字,每選擇一個數字,就把target減去此數字;

當target等於0時,則記錄此path,小於0的時候直接返回,大於0的時候繼續;

如果遍歷候選陣列進行選取會出現場重複,所以用一個pos記錄當前選取數字的位置;

每次只能從當前數字出發,往後選取即可:

程式碼

class Solution {
public:
    int candidatesLength;
    vector<vector<int>> ans;
    void dfs(vector<int>& path, int target, vector<int>& candidates, int pos) {
        if (target == 0) {
            ans.push_back(path);
            return;
        }
        if (target < 0) return;
        for (int i=pos; i<candidatesLength; i++) {
            int x = candidates[i];
            path.push_back(x);
            dfs(path, target-x, candidates, i);
            path.pop_back();
        }
    } 
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        candidatesLength = candidates.size();
        if (candidatesLength <= 0) return ans;
        vector<int> path;
        dfs(path, target, candidates, 0);
        return ans;
    }
};