leetcode —— 39. 組合總和

給定一個無重複元素的數組 candidates 和一個目標數 target ,找出 candidates 中所有可以使數字和爲 target 的組合。candidates 中的數字可以無限制重複被選取。

說明:

  • 所有數字(包括 target)都是正整數。
  • 解集不能包含重複的組合。

示例 1:

輸入: candidates = [2,3,6,7], target = 7,
所求解集爲:
[
[7],
[2,2,3]
]

解題思路:使用遞歸+回溯,爲了避免組合出現重複,例如示例1中的重複組合[2,2,3]和[3,2,2],可以先對輸入candidates進行排序,然後在遞歸的時候,設temp爲當前組合,下一個可以放進temp中的數,一定大於等於temp[-1]。

其Python3代碼如下:

# Python3
class Solution:
    def __init__(self):
        self.ans = []
    def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
        if not candidates:
            return []
        def combSums(candidates,target,temp,sums):
            if target == sums:  # 遞歸停止條件
                self.ans.append(temp[:])
                return

            for n in candidates:  # 遍歷每種情況
                if sums + n > target:  # 如果當前sums值大於target,直接break
                    break
                if temp and n < temp[-1]:  # 如果當前輸入的值小於temp[-1]則continue
                    continue
                temp.append(n)
                combSums(candidates,target,temp,sums+n)
                temp.pop()  # 回溯
        candidates.sort()  # 執行遞歸時先進行排序
        combSums(candidates,target,[],0)
        return self.ans

其C++代碼如下:

# C++
class Solution {
private:
    vector<vector<int>> num;
    vector<int> sum;
    int i = 0;
public:
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) 
    {
        sort(candidates.begin(),candidates.end());
        function(candidates,target,sum,i);
        return num;
    }
    void function(vector<int>& candidate, int target,vector<int> sum,int i)
    {
        if(target==0)
        {
            num.push_back(sum);
        }        
        for(;i<candidate.size();++i)  # 只遍歷比當前數字大的candidates數字
        {
            if(candidate[i]<=target)
            {
                sum.push_back(candidate[i]); 
                function(candidate,target-candidate[i],sum,i);
                sum.pop_back();
            }
        }
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章