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

更新於 2024/12/22閱讀時間約 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ᵐ)
    • 與回溯法不同,這裡需要儲存所有的組合結果,佔用額外的空間。

總結

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

歡迎來到我的部落格!這裡記錄了軟體工程師的日常生活點滴,並分享程式設計與演算法的實用教學。無論你是初學者還是有經驗的開發者,都能在這裡找到深入淺出的技術解析與實戰技巧。此外,我也會分享工作中的心路歷程與學習心得,讓你不僅學到技術,更能瞭解軟體開發的實際應用與挑戰。希望透過這個平台,能與你共同成長,激發對技術的熱情!
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
給定一個長度為 n 的整數數組 nums 和一個整數target,在 nums 中找到三個整數,使得總和最接近target。傳回三個整數的總和。可以假設每個輸入都有一個解決方案。
給定整數陣列nums,傳回所有三元組[nums[i], nums[j], nums[k]],使得i != j, i != k, j != k,且nums[i ] + nums[j] + nums[k] == 0。
在這篇文章中,我們將深入剖析 LeetCode 題目 13. Roman to Integer 的解題方法。這是一道經典題目,要求我們將羅馬數字轉換為整數表示。通過學習這篇教學,你將掌握如何處理羅馬數字的規則和高效地實現轉換。
在這篇文章中,我們將探討 LeetCode 題目 12. Integer to Roman 的解題方法。這是一道經典的模擬題,要求我們將整數轉換為羅馬數字表示。通過這篇文章,你將學會如何高效地解決這道題,並理解羅馬數字的基本規則和轉換技巧。
這篇文章將介紹 LeetCode 題目 11. Container With Most Water。這是一道經典的雙指針問題,題目要求我們找到容器可以盛最多水的情況,並幫助我們理解如何通過移動左右指針來最大化結果。
這篇文章將介紹 LeetCode 題目 10. Regular Expression Matching,這是一道有趣且具有挑戰性的動態規劃題目,涉及實現一個正則表達式匹配算法。這道題目主要考察對正則表達式中的特殊字符 . 和 * 的理解和處理,並運用動態規劃進行高效求解。
給定一個長度為 n 的整數數組 nums 和一個整數target,在 nums 中找到三個整數,使得總和最接近target。傳回三個整數的總和。可以假設每個輸入都有一個解決方案。
給定整數陣列nums,傳回所有三元組[nums[i], nums[j], nums[k]],使得i != j, i != k, j != k,且nums[i ] + nums[j] + nums[k] == 0。
在這篇文章中,我們將深入剖析 LeetCode 題目 13. Roman to Integer 的解題方法。這是一道經典題目,要求我們將羅馬數字轉換為整數表示。通過學習這篇教學,你將掌握如何處理羅馬數字的規則和高效地實現轉換。
在這篇文章中,我們將探討 LeetCode 題目 12. Integer to Roman 的解題方法。這是一道經典的模擬題,要求我們將整數轉換為羅馬數字表示。通過這篇文章,你將學會如何高效地解決這道題,並理解羅馬數字的基本規則和轉換技巧。
這篇文章將介紹 LeetCode 題目 11. Container With Most Water。這是一道經典的雙指針問題,題目要求我們找到容器可以盛最多水的情況,並幫助我們理解如何通過移動左右指針來最大化結果。
這篇文章將介紹 LeetCode 題目 10. Regular Expression Matching,這是一道有趣且具有挑戰性的動態規劃題目,涉及實現一個正則表達式匹配算法。這道題目主要考察對正則表達式中的特殊字符 . 和 * 的理解和處理,並運用動態規劃進行高效求解。
你可能也想看
Google News 追蹤
Thumbnail
徵的就是你 🫵 超ㄅㄧㄤˋ 獎品搭配超瞎趴的四大主題,等你踹共啦!還有機會獲得經典的「偉士牌樂高」喔!馬上來參加本次的活動吧!
Thumbnail
隨著理財資訊的普及,越來越多台灣人不再將資產侷限於台股,而是將視野拓展到國際市場。特別是美國市場,其豐富的理財選擇,讓不少人開始思考將資金配置於海外市場的可能性。 然而,要參與美國市場並不只是盲目跟隨標的這麼簡單,而是需要策略和方式,尤其對新手而言,除了選股以外還會遇到語言、開戶流程、Ap
Thumbnail
題目敘述 Combination Sum II_Leetcode #40 給定一個整數陣列candidates 和 目標值target。 每個陣列元素只能選擇一次,請問有多少種組合方法,可以使得組合數總和 = target? 請把滿足組合數總和 = target的組合方法以陣列的形式返回答案
Thumbnail
題目敘述 Combination Sum IV 給定一個輸入陣列nums,和目標值target,從nums裡面挑數字去湊出總和 = target,數字可以重複挑選。 請問有多少排列數可以湊出target? 註: 排列數的意思就是位置不同代表兩種不同的方法數。
Thumbnail
Append Characters to String to Make Subsequence 給定兩個字串s和字串t。 請計算最少的字元串接數量是多少,串接在s的尾端,使得t是s的子序列。 測試範例 Example 1: Input: s = "coaching", t =
Thumbnail
題目敘述 題目會給定我們一個輸入陣列nums,要求我們掃描美個陣列元素nums[i],計算除了nums[i]以外的陣列元素連乘積。 題目的原文敘述 測試範例 Example 1: Input: nums = [1,2,3,4] Output: [24,12,8,6] nums[0] 以
Thumbnail
題目敘述 題目會給我們一個字串s。 要求我們移除字串中的星號,還有刪除星號左手邊最靠近的第一個字元。 以字串的形式返回輸出答案。 題目的原文敘述 測試範例 Example 1: Input: s = "leet**cod*e" Output: "lecoe" Explanation:
Thumbnail
題目敘述 題目會給定一個輸入字串s和一套編碼規則,要求我們針對字串s進行解碼,並且以字串的形式返回答案。 編碼規則: 數字[字串] -> []內的字串以對應倍數做展開,而且允許巢狀編碼。 例如: 3[a] 解碼完就是 aaa 2[bc] 解碼完就是 bcbc 2[a2[b]] = 2
Thumbnail
題目敘述 題目會給定我們兩個輸入字串word1, word2,要求我們依照word1,word2,word1,word2, ... 交叉前進的方式,合併兩個字串,作為輸出。 題目的原文敘述 測試範例 Example 1: Input: word1 = "abc", word2 = "pq
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
題目敘述 題目會給定我們兩個字串word1 和 word2。 允許我們不限制次數進行下列兩種操作: 任意調換其中兩個字元的位置。 把字串中的某個字元全部置換成另一個字元,同時把另一個字元同時置換成某個字元。(例如把字串中原本的a都換成b,把原本的b都換成a) 問我們能不能通過上述兩項操作,
Thumbnail
徵的就是你 🫵 超ㄅㄧㄤˋ 獎品搭配超瞎趴的四大主題,等你踹共啦!還有機會獲得經典的「偉士牌樂高」喔!馬上來參加本次的活動吧!
Thumbnail
隨著理財資訊的普及,越來越多台灣人不再將資產侷限於台股,而是將視野拓展到國際市場。特別是美國市場,其豐富的理財選擇,讓不少人開始思考將資金配置於海外市場的可能性。 然而,要參與美國市場並不只是盲目跟隨標的這麼簡單,而是需要策略和方式,尤其對新手而言,除了選股以外還會遇到語言、開戶流程、Ap
Thumbnail
題目敘述 Combination Sum II_Leetcode #40 給定一個整數陣列candidates 和 目標值target。 每個陣列元素只能選擇一次,請問有多少種組合方法,可以使得組合數總和 = target? 請把滿足組合數總和 = target的組合方法以陣列的形式返回答案
Thumbnail
題目敘述 Combination Sum IV 給定一個輸入陣列nums,和目標值target,從nums裡面挑數字去湊出總和 = target,數字可以重複挑選。 請問有多少排列數可以湊出target? 註: 排列數的意思就是位置不同代表兩種不同的方法數。
Thumbnail
Append Characters to String to Make Subsequence 給定兩個字串s和字串t。 請計算最少的字元串接數量是多少,串接在s的尾端,使得t是s的子序列。 測試範例 Example 1: Input: s = "coaching", t =
Thumbnail
題目敘述 題目會給定我們一個輸入陣列nums,要求我們掃描美個陣列元素nums[i],計算除了nums[i]以外的陣列元素連乘積。 題目的原文敘述 測試範例 Example 1: Input: nums = [1,2,3,4] Output: [24,12,8,6] nums[0] 以
Thumbnail
題目敘述 題目會給我們一個字串s。 要求我們移除字串中的星號,還有刪除星號左手邊最靠近的第一個字元。 以字串的形式返回輸出答案。 題目的原文敘述 測試範例 Example 1: Input: s = "leet**cod*e" Output: "lecoe" Explanation:
Thumbnail
題目敘述 題目會給定一個輸入字串s和一套編碼規則,要求我們針對字串s進行解碼,並且以字串的形式返回答案。 編碼規則: 數字[字串] -> []內的字串以對應倍數做展開,而且允許巢狀編碼。 例如: 3[a] 解碼完就是 aaa 2[bc] 解碼完就是 bcbc 2[a2[b]] = 2
Thumbnail
題目敘述 題目會給定我們兩個輸入字串word1, word2,要求我們依照word1,word2,word1,word2, ... 交叉前進的方式,合併兩個字串,作為輸出。 題目的原文敘述 測試範例 Example 1: Input: word1 = "abc", word2 = "pq
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
題目敘述 題目會給定我們兩個字串word1 和 word2。 允許我們不限制次數進行下列兩種操作: 任意調換其中兩個字元的位置。 把字串中的某個字元全部置換成另一個字元,同時把另一個字元同時置換成某個字元。(例如把字串中原本的a都換成b,把原本的b都換成a) 問我們能不能通過上述兩項操作,