1. 程式人生 > >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]
]

這個題和PathSum這類題類似,所以思路這次採用遞迴,用深度搜索的方式來找到所有的集合,方法直接從程式碼看就可以,這裡說一下python淺複製和深複製,用等於號和copy都是淺複製,深複製的方法是copy.deepcopy(name),只有這樣才算是深度複製,否則都是相當於一個引用,改變name值時另一個被賦值的值也會跟著改。
C++原始碼:

class Solution {
public:
    vector<vector<int>> combinationSum(vector<int>& candidates, int target)
{ vector<vector<int>> res; sort(candidates.begin(), candidates.end()); combinationSumDFS(candidates, target, 0, {}, res); return res; } void combinationSumDFS(vector<int>& candidates, int target, int start, vector<int> out, vector<
vector<int>>& res) { if(target < 0) return; else if(target == 0) { res.push_back(out); return; } for(int i=start;i<candidates.size();i++) { out.push_back(candidates[i]); combinationSumDFS(candidates, target-candidates[i], i, out, res); out.pop_back(); } } };

python3原始碼:

class Solution:
    def combinationSum(self, candidates, target):
        """
        :type candidates: List[int]
        :type target: int
        :rtype: List[List[int]]
        """
        res = []
        out = []
        candidates.sort()
        self.combinationSumDFS(candidates, target, 0, out, res)
        return res
    
    def combinationSumDFS(self, candidates, target, start, out, res):
        if target < 0:
            return
        elif target == 0:
            res.append(copy.deepcopy(out))
            return
        for i in range(start, len(candidates)):
            out.append(candidates[i])
            self.combinationSumDFS(candidates, target-candidates[i], i, out, res)
            out.pop()