程式碼隨想錄演算法訓練營第22天 | 77.組合 216.組合總和 17.電話號碼的字母組合

Y荷兰豆Y發表於2024-06-27

77.組合

給定兩個整數 n 和 k,返回 1 ... n 中所有可能的 k 個數的組合。

解題

只能取比它大的,所以有個引數startindex
引數:一維陣列單個組合path,二維陣列結果集result,總數n,組合大小k,搜尋結果的開始索引startindex
終止條件:path.size=k

點選檢視程式碼
class Solution:
    def combine(self, n: int, k: int) -> List[List[int]]:
        result=[]
        self.backtracking(n,k,1,[],result)
        return result
    def backtracking(self,n,k,startIndex,path,result):
        if len(path)==k:
            result.append(path[:])
            return
        for i in range(startIndex,n+1):
            path.append(i)
            self.backtracking(n,k,i+1,path,result)
            path.pop()

剪枝最佳化:剪掉的是節點的子孩子,所以改為:
還需要選取的元素的個數 k-len(path)
至多從那裡開始搜尋 n-(k-len(path))+1
python的range範圍左閉右開,所以 for i in range(startIndex,n-(k-len(path))+2):

216.組合總和

找出所有相加之和為 n 的 k 個數的組合。組合中只允許含有 1 - 9 的正整數,並且每種組合中不存在重複的數字。
說明:
所有數字都是正整數。
解集不能包含重複的組合。

解題

跟上面差不多,多了個縱向剪枝,多了個引數和判斷currentSum

點選檢視程式碼
class Solution:
    def combinationSum3(self, k: int, n: int) -> List[List[int]]:
        result=[]
        self.backtracking(n,k,0,1,[],result)
        return result
    def backtracking(self,targetSum,k,currentSum,startIndex,path,result):
        if currentSum>targetSum:
            return
        if len(path)==k:
            if currentSum==targetSum:
                result.append(path[:])
            return
        for i in range(startIndex,9-(k-len(path))+2):
            currentSum+=i
            path.append(i)
            self.backtracking(targetSum,k,currentSum,i+1,path,result)
            currentSum-=i
            path.pop()

17.電話號碼的字母組合

給定一個僅包含數字 2-9 的字串,返回所有它能表示的字母組合。答案可以按 任意順序 返回。
給出數字到字母的對映如下(與電話按鍵相同)。注意 1 不對應任何字母。

解題

引數:字串digits,index
上兩題是在一個集合裡找組合,需要startIndex避免已經用過的元素,這裡是在兩個集合裡找,用Index
終止:index==len(digits),因為index從0開始,所以此時指向號碼後一位,以防最後一個數字不處理了

字串的增刪:

點選檢視程式碼
s=""
s += letters[i] 
s = self.s[:-1] 

看答案裡result和s都寫在全域性變數裡self.result,遞迴函式的傳遞引數就不用result和s了,我還是照老的寫的

點選檢視程式碼
class Solution:
    def __init__(self):
        self.letterMap=[
            "",
            "",
            "abc",
            "def",
            "ghi",
            "jkl",
            "mno",
            "pqrs",
            "tuv",
            "wxyz"
        ]
    
    def backtracking(self,digits,index,result,s):
        if index==len(digits):
            result.append(s)
            return
        #找到當前遞迴層index對應的數字和相映的字母
        digit=int(digits[index])
        letters=self.letterMap[digit]
        for i in range(len(letters)):
            s+=letters[i]
            self.backtracking(digits,index+1,result,s)
            s=s[:-1]

    def letterCombinations(self, digits: str) -> List[str]:
        if len(digits)==0:
            return []
        result=[]
        self.backtracking(digits,0,result,"")
        return result

相關文章