[LeetCode解題攻略] 17. Letter Combinations of a Phone Number

更新於 發佈於 閱讀時間約 7 分鐘

題目描述

給定一個包含 2 到 9 之間數字的字串,傳回該數字可以表示的所有可能的字母組合。以任意順序回傳答案。

下圖為數字對字母的映射(就像電話按鈕一樣)。請注意數字 1 不映射到任何字母。

raw-image



  1. 範例 1
    Input: digits = "23"
    Output: ["ad","ae","af","bd","be","bf","cd","ce","cf"]
  2. 範例 2
    Input: digits = ""
    Output: []
  3. 範例 3
    Input: digits = "2"
    Output: ["a","b","c"]

解題思路

  1. 利用回溯法來生成所有可能的字母組合。
  2. 將數字對應到字母,類似於多層迴圈。
  3. 特殊情況處理:若輸入字串為空,直接返回空陣列。

解法 1:回溯法

思路

  • 每個數字對應的字母表現為樹的不同層次。
  • 我們從數字字串的第一個數字開始,逐步選擇其對應的字母,並繼續對下一個數字執行同樣的操作,直到遍歷完整個字串。
  • 每當我們生成一個完整的字母組合時,將其加入結果列表中。

詳細步驟

  1. 定義數字到字母的對應關係,使用字典進行映射。
  2. 檢查輸入字串是否為空,若空直接返回空列表。
  3. 使用回溯法逐步生成字母組合:
    • 如果當前深度等於輸入字串長度,將組合加入結果。
    • 遍歷當前數字對應的所有字母,遞歸地處理下一個數字。

實現 (Python)

class Solution:
def letterCombinations(self, digits: str) -> List[str]:
# 數字到字母的映射
phone_map = {
"2": "abc", "3": "def", "4": "ghi", "5": "jkl",
"6": "mno", "7": "pqrs", "8": "tuv", "9": "wxyz"
}

# 如果輸入為空,返回空列表
if not digits:
return []

# 回溯函數
def backtrack(index, path):
# 如果字母組合完成,加入結果
if index == len(digits):
combinations.append("".join(path))
return

# 獲取當前數字對應的字母
possible_letters = phone_map[digits[index]]
for letter in possible_letters:
# 選擇字母,進一步遞歸
path.append(letter)
backtrack(index + 1, path)
# 回溯:移除剛剛加入的字母
path.pop()

# 結果列表
combinations = []
backtrack(0, [])
return combinations

時間與空間複雜度

  • 時間複雜度:O(3ⁿ × 4ᵐ)
    • 其中 n 是對應於數字 2, 3, 4, 5, 6, 8(每個數字對應 3 個字母)的數量,m 是對應於數字 7, 9(每個數字對應 4 個字母)的數量。
    • 最壞情況下,每個數字都對應 4 個字母,總共有 4^k 種組合,k 是輸入字串的長度。
  • 空間複雜度:O(k)
    • 主要來自於遞歸調用堆疊和暫存的路徑 path,k 是輸入字串的長度。

解法 2:迭代法

思路

  • 將字母組合問題轉換為多層嵌套的迴圈。
  • 使用隊列(Queue)儲存部分結果,逐步處理每個數字。
  • 每次處理一個數字時,將隊列中已有的組合與當前數字對應的字母進行拼接。

詳細步驟

  1. 初始化隊列為空,將第一個數字的所有字母加入隊列。
  2. 遍歷剩下的數字,對每個數字對應的字母與隊列中現有的組合進行拼接。
  3. 返回最終的隊列內容。

實現 (Python)

class Solution:
def letterCombinations(self, digits: str) -> List[str]:
# 數字到字母的映射
phone_map = {
"2": "abc", "3": "def", "4": "ghi", "5": "jkl",
"6": "mno", "7": "pqrs", "8": "tuv", "9": "wxyz"
}

# 如果輸入為空,返回空列表
if not digits:
return []

# 初始化隊列
queue = deque([""])

for digit in digits:
for _ in range(len(queue)):
combination = queue.popleft()
for letter in phone_map[digit]:
queue.append(combination + letter)

return list(queue)

時間與空間複雜度

  • 時間複雜度:O(3ⁿ × 4ᵐ)
    • 與回溯法相同,每個數字都可能對應多個字母,所有組合的生成時間是指數級的。
  • 空間複雜度:O(3ⁿ × 4ᵐ)
    • 與回溯法不同,這裡需要儲存所有的組合結果,佔用額外的空間。

總結

這題適合初學者熟悉回溯法的核心概念與應用,也可以幫助理解如何用迭代法替代遞歸方法來解決問題。

留言
avatar-img
留言分享你的想法!
avatar-img
追極光的北極熊|軟體工程師的小天地
8會員
141內容數
歡迎來到我的部落格!這裡記錄了軟體工程師的日常生活點滴,並分享程式設計與演算法的實用教學。無論你是初學者還是有經驗的開發者,都能在這裡找到深入淺出的技術解析與實戰技巧。此外,我也會分享工作中的心路歷程與學習心得,讓你不僅學到技術,更能瞭解軟體開發的實際應用與挑戰。希望透過這個平台,能與你共同成長,激發對技術的熱情!
2025/04/04
給定一個非負整數陣列 nums,其中 nums[i] 代表你在索引 i 處最多可以向右跳幾步。 請判斷是否能夠從索引 0 跳到最後一個索引。
2025/04/04
給定一個非負整數陣列 nums,其中 nums[i] 代表你在索引 i 處最多可以向右跳幾步。 請判斷是否能夠從索引 0 跳到最後一個索引。
2025/03/28
給定一個 m x n 的矩陣 matrix,請按照 螺旋順序(spiral order) 返回矩陣中的所有元素。
2025/03/28
給定一個 m x n 的矩陣 matrix,請按照 螺旋順序(spiral order) 返回矩陣中的所有元素。
2025/03/20
這道題是 LeetCode 的經典題之一,要求我們找出 一個子陣列,使其和最大,並返回這個最大和的數值。
2025/03/20
這道題是 LeetCode 的經典題之一,要求我們找出 一個子陣列,使其和最大,並返回這個最大和的數值。
看更多
你可能也想看
Thumbnail
「欸!這是在哪裡買的?求連結 🥺」 誰叫你太有品味,一發就讓大家跟著剁手手? 讓你回購再回購的生活好物,是時候該介紹出場了吧! 「開箱你的美好生活」現正召喚各路好物的開箱使者 🤩
Thumbnail
「欸!這是在哪裡買的?求連結 🥺」 誰叫你太有品味,一發就讓大家跟著剁手手? 讓你回購再回購的生活好物,是時候該介紹出場了吧! 「開箱你的美好生活」現正召喚各路好物的開箱使者 🤩
Thumbnail
Leetcode #1945. Sum of Digits of String After Convert 給定一個由小寫字母組成的字串 s ,以及一個整數 k 。 首先,用英文字母順序的位置替換每個字母,將 s 轉換 為整數 並且計算digits sum,反覆迭代k次。
Thumbnail
Leetcode #1945. Sum of Digits of String After Convert 給定一個由小寫字母組成的字串 s ,以及一個整數 k 。 首先,用英文字母順序的位置替換每個字母,將 s 轉換 為整數 並且計算digits sum,反覆迭代k次。
Thumbnail
Append Characters to String to Make Subsequence 給定兩個字串s和字串t。 請計算最少的字元串接數量是多少,串接在s的尾端,使得t是s的子序列。 測試範例 Example 1: Input: s = "coaching", t =
Thumbnail
Append Characters to String to Make Subsequence 給定兩個字串s和字串t。 請計算最少的字元串接數量是多少,串接在s的尾端,使得t是s的子序列。 測試範例 Example 1: Input: s = "coaching", t =
Thumbnail
題目敘述 題目會給定一個輸入字串s和一套編碼規則,要求我們針對字串s進行解碼,並且以字串的形式返回答案。 編碼規則: 數字[字串] -> []內的字串以對應倍數做展開,而且允許巢狀編碼。 例如: 3[a] 解碼完就是 aaa 2[bc] 解碼完就是 bcbc 2[a2[b]] = 2
Thumbnail
題目敘述 題目會給定一個輸入字串s和一套編碼規則,要求我們針對字串s進行解碼,並且以字串的形式返回答案。 編碼規則: 數字[字串] -> []內的字串以對應倍數做展開,而且允許巢狀編碼。 例如: 3[a] 解碼完就是 aaa 2[bc] 解碼完就是 bcbc 2[a2[b]] = 2
Thumbnail
題目敘述 題目會給我們一個參數k 和 目標值n。 請問我們從1~9內挑k個相異的數字,使得他們的總和為n 的組合數有多少? 挑選時,每個數字必須相異,而且每個數字只能選一次。 題目的原文敘述 測試範例 Example 1: Input: k = 3, n = 7 Output: [
Thumbnail
題目敘述 題目會給我們一個參數k 和 目標值n。 請問我們從1~9內挑k個相異的數字,使得他們的總和為n 的組合數有多少? 挑選時,每個數字必須相異,而且每個數字只能選一次。 題目的原文敘述 測試範例 Example 1: Input: k = 3, n = 7 Output: [
Thumbnail
題目敘述 題目會給我們一個傳統手機的數字鍵盤 和一個數字鍵的輸入字串digits,要求我們列舉出所有輸入字串digits可能對應到的英文字母的排列。 例如輸入digits="23" 那對應到的英文字母排列就是"ad", "ae", "af", "bd", "be", "bf", "cd", "
Thumbnail
題目敘述 題目會給我們一個傳統手機的數字鍵盤 和一個數字鍵的輸入字串digits,要求我們列舉出所有輸入字串digits可能對應到的英文字母的排列。 例如輸入digits="23" 那對應到的英文字母排列就是"ad", "ae", "af", "bd", "be", "bf", "cd", "
Thumbnail
題目敘述 題目會給我們一個陣列,要求我們返回 兩數之和=target所在的陣列索引值。 題目還額外保證,一定剛好有一組解。 測試範例 Example 1: Input: nums = [2,7,11,15], target = 9 Output: [0,1]
Thumbnail
題目敘述 題目會給我們一個陣列,要求我們返回 兩數之和=target所在的陣列索引值。 題目還額外保證,一定剛好有一組解。 測試範例 Example 1: Input: nums = [2,7,11,15], target = 9 Output: [0,1]
Thumbnail
題目會給我們一個字串陣列nums,內容都是二進位字串,要求我們造出一個另一個相等長度,新的二進位字串,而且不和字串陣列nums內的重複。 答案可能有不只一組,回傳合任一組合法的答案皆可。
Thumbnail
題目會給我們一個字串陣列nums,內容都是二進位字串,要求我們造出一個另一個相等長度,新的二進位字串,而且不和字串陣列nums內的重複。 答案可能有不只一組,回傳合任一組合法的答案皆可。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News