17. Letter Combinations of a Phone Number

Photo by MarinelA Pavlovic on Unsplash
Photo by MarinelA Pavlovic on Unsplash
這題要我們列出所有的可能字串,因此可以想到要用 backtracking 來解。

Problem

Given a string containing digits from 2-9 inclusive, return all possible letter combinations that the number could represent. Return the answer in any order.

A mapping of digits to letters (just like on the telephone buttons) is given below. Note that 1 does not map to any letters.

Example 1:

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

Example 2:

Input: digits = ""
Output: []

Example 3:

Input: digits = "2"
Output: ["a","b","c"]

Constraints:

  • 0 <= digits.length <= 4
  • digits[i] is a digit in the range ['2', '9'].

Solution

這題要我們列出所有的可能字串,因此可以想到要用 backtracking 來解。在處理每個 digit 時,我們將 digit 對應的 letter 附加到 prefix 字串中,等處理到最後一個 digit 時,prefix 就會是其中一個對應字串。因為我們必須不斷地將 letter 附加到 prefix,再將 letter 從 prefix 中移除,所以我們不可以使用 String。如果使用 String 的話,每次對 String 附加或移除 letter 時,它都會建立一個新的 String,而這非常地耗效能。我們可以使用 StringBuilder 作為替代。

Backtracking

  • Time: O(n4^n)
  • Space: O(4^n)
class Solution {
    public List<String> letterCombinations(String digits) {
        List<String> results = new ArrayList<>();
        if (digits == null || digits.length() == 0) return results;

        Map<Character, char[]> map = buildDigitMap();
        dfs(digits, 0, map, new StringBuilder(), results);
        return results;
    }

    private Map<Character, char[]> buildDigitMap() {
        Map<Character, char[]> map = new HashMap<>();
        map.put('2', new char[]{'a', 'b', 'c'});
        map.put('3', new char[]{'d', 'e', 'f'});
        map.put('4', new char[]{'g', 'h', 'i'});
        map.put('5', new char[]{'j', 'k', 'l'});
        map.put('6', new char[]{'m', 'n', 'o'});
        map.put('7', new char[]{'p', 'q', 'r', 's'});
        map.put('8', new char[]{'t', 'u', 'v'});
        map.put('9', new char[]{'w', 'x', 'y', 'z'});
        return map;
    }

    private void dfs(String digits, int index, Map<Character, char[]> map, StringBuilder prefix, List<String> results) {
        if (index >= digits.length()) return;

        char c = digits.charAt(index);
        boolean isLast = index == digits.length() - 1;
        char[] letters = map.get(c);
        for (char d : letters) {
            prefix.append(d);
            if (isLast) {
                results.add(prefix.toString());
            } else {
                dfs(digits, index + 1, map, prefix, results);
            }
            prefix.deleteCharAt(prefix.length() - 1);
        }
    }
}

參考

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

You May Also Like
Photo by Oladimeji Odunsi on Unsplash
Read More

72. Edit Distance

在解此題時,我們要先觀察 word1 如何變成 word2。以 Example1 為例,左下圖列出 “horse” 轉變成 “ros” 的 distance。表中,縱軸表示 “horse”,而橫軸表示 “ros”。
Read More
Photo by Diana Parkhouse on Unsplash
Read More

1048. Longest String Chain

此題中,wordA 是 wordB 的 predecessor 指只要插入一個 letter 到 wordA,那就會使得它和 wordB 一樣。然而,插入一個 letter 到一個地方,就要考慮 26 種字母。這使得整體的複雜度上升。
Read More
Photo by Bogdan Farca on Unsplash
Read More

39. Combination Sum

此題要我們列出所有可能的組合,所以我們可能用 backtracking 來找。但是,我們必須避免找到相同的組合。當兩個組合裡的數字和個數都依一樣,但順序不一樣時,他們依然是相同的組合。
Read More