LeetCode 17*/46*. 電話號碼的字母組合/全排列(回溯法)(Python)

給定一個僅包含數字 2-9 的字符串,返回所有它能表示的字母組合。

給出數字到字母的映射如下(與電話按鍵相同)。注意 1 不對應任何字母。

示例:

輸入:"23"
輸出:["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].

思路:暴力破解,回溯法

利用樹形結構如圖 

將digits數組中每一位數字對應的字母依次取出來,再加上後面位置的數字所代表的的所有字母依次遞歸。。。

class Solution:

    res = []

    letterMap = {
        "0": " ",
        "1": "",
        "2": "abc",
        "3": "def",
        "4": "ghi",
        "5": "jkl",
        "6": "mno",
        "7": "pqrs",
        "8": "tuv",
        "9": "wxyz",
    }

    def letterCombinations(self, digits: str) -> List[str]:
        # 一定要清除成員變量,否則下個測試用例中會有上一次的結果
        self.res = []

        if digits == "":
            return self.res
        self.findCombination(digits, 0, "")

        return self.res

    # s中保存此時從digits[0...index-1]數字組合中得到的一個字符串
    # 將digits[index]對應的字母添加到s中
    def findCombination(self, digits: str, index: int, s: str):
        if index == len(digits):
            self.res.append(s)
            return
        
        num = digits[index]
        letters = self.letterMap[num]
        for l in letters:
            self.findCombination(digits, index + 1, s + l)
        
        return

 這裏使用了類的成員變量來存儲最後的結果,注意一定要有 self.res = [] 這一步,否則leetcode上測試的前一個計算結果會保存下來影響後面的判斷

 

給定一個沒有重複數字的序列,返回其所有可能的全排列。

示例:

輸入: [1,2,3]
輸出:
[
  [1,2,3],
  [1,3,2],
  [2,1,3],
  [2,3,1],
  [3,1,2],
  [3,2,1]
]

思路:和第17題類似,都採用回溯法,代碼整體框架不變,需要注意:

① 上一題中數字的順序不變,例如[2, 3, 4],最後的結果就是輸出2,3,4所代表的字母的排列,而本題意思是結果中可能含有[4,3,2]......,所以數字順序可變,因此需要另外一個數組used記錄已經使用過的數字

② 使用回溯法時,遞歸出來之後要注意及時回覆狀態,例如從[1,2,3]出來,返回到[1,2,X]時,需要將3這個數字在used中重新記爲未使用過,並將[1,2,3]變爲[1,2],此題更能體現回溯思想

python中深拷貝淺拷貝的問題。。。坑了我10分鐘的時間調試

class Solution:

    res = []
    used = []

    def permute(self, nums: List[int]) -> List[List[int]]:
        self.res = []
        self.used = [0 for _ in nums]

        if len(nums) == 0:
            return []
        p = []
        self.generatePermutation(nums, 0, p)

        return self.res

    def generatePermutation(self, nums: List[int], index: int, p: List[int]):
        if index == len(nums):
            self.res.append(p.copy())   # 深複製,淺複製,好坑啊~~
            return
        
        for i in range(len(nums)):
            if self.used[i] == 0:
                p.append(nums[i])
                self.used[i] = 1
                self.generatePermutation(nums, index + 1, p)
                # 回溯到上一狀態
                p.pop()
                self.used[i] = 0
        return

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章