Medium草稿★★★★O(4^n * n) 時間 · O(n) 空間
BacktrackingStringHash Table
Patterns🌿 回溯#️⃣ 雜湊
尚未複習過

解法已隱藏 — 先讀題目敘述、自己想想看,再點上方按鈕揭曉。

17Letter Combinations of a Phone NumberBacktrackingMediumBacktracking

給定一個包含 2-9 數字的字串,回傳所有該數字組合能代表的字母組合(按手機九宮格鍵盤的對應)。答案可以任意順序回傳。

Example:

Input: digits = “23” Output: [“ad”,“ae”,“af”,“bd”,“be”,“bf”,“cd”,“ce”,“cf”]

Intuition

TIP

核心思路:每個數字對應 3-4 個字母,逐位數字展開所有可能的字母選擇,就是一棵回溯搜尋樹。

Approaches

1. Iterative (BFS-style) — O(4^n * n) / O(4^n * n)
  • Idea: 逐個數字處理,對每個數字,將現有的所有組合各自擴展新字母
  • Time: O(4^n * n) - n 為 digits 長度
  • Space: O(4^n * n) - 存所有組合
class Solution {
    fun letterCombinations(digits: String): List<String> {
        if (digits.isEmpty()) return emptyList()

        val mapping = mapOf(
            '2' to "abc", '3' to "def", '4' to "ghi", '5' to "jkl",
            '6' to "mno", '7' to "pqrs", '8' to "tuv", '9' to "wxyz"
        )

        var result = listOf("")
        for (digit in digits) {
            val letters = mapping[digit]!!
            result = result.flatMap { combo ->
                letters.map { combo + it }
            }
        }
        return result
    }
}
⭐ 2. Backtracking — O(4^n * n) / O(n)
  • Idea: 逐位數字選擇字母,遞迴到底就得到一個完整組合
  • Time: O(4^n * n) - 最多 4^n 個組合
  • Space: O(n) - 遞迴深度
class Solution {
    fun letterCombinations(digits: String): List<String> {
        if (digits.isEmpty()) return emptyList()

        val mapping = mapOf(
            '2' to "abc", '3' to "def", '4' to "ghi", '5' to "jkl",
            '6' to "mno", '7' to "pqrs", '8' to "tuv", '9' to "wxyz"
        )

        val result = mutableListOf<String>()
        val sb = StringBuilder()

        fun backtrack(index: Int) {
            if (index == digits.length) {
                result.add(sb.toString())
                return
            }

            val letters = mapping[digits[index]]!!
            for (letter in letters) {
                sb.append(letter)
                backtrack(index + 1)
                sb.deleteCharAt(sb.lastIndex)
            }
        }

        backtrack(0)
        return result
    }
}

🔑 Takeaways