Backtracking_17. 電話號碼的字母組合
阿新 • • 發佈:2020-07-23
給定一個僅包含數字2-9的字串,返回所有它能表示的字母組合。
給出數字到字母的對映如下(與電話按鍵相同)。注意 1 不對應任何字母。
示例:
輸入:"23"
輸出:["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].
說明:
儘管上面的答案是按字典序排列的,但是你可以任意選擇答案輸出的順序。
來源:力扣(LeetCode)
連結:https://leetcode-cn.com/problems/letter-combinations-of-a-phone-number
思路:
Backtracking(回溯)屬於 DFS。有很多經典的問題,如八皇后。
- 普通 DFS 主要用在可達性問題,這種問題只需要執行到特點的位置然後返回即可。
- 而 Backtracking 主要用於求解排列組合問題,例如有 { 'a','b','c' } 三個字元,求解所有由這三個字元排列得到的字串,這種問題在執行到特定的位置返回之後還會繼續執行求解過程。
因為 Backtracking 不是立即返回,而要繼續求解,因此在程式實現時,需要注意對元素的標記問題:
- 在訪問一個新元素進入新的遞迴呼叫時,需要將新元素標記為已經訪問,這樣才能在繼續遞迴呼叫時不用重複訪問該元素;
- 但是在遞迴返回時,需要將元素標記為未訪問,因為只需要保證在一個遞迴鏈中不同時訪問一個元素,可以訪問已經訪問過但是不在當前遞迴鏈中的元素。
class Solution { private static final String[] KEYS = {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"}; public List<String> letterCombinations(String digits) { List<String> combinations = new ArrayList<>(); if (digits == null || digits.length() == 0) {return combinations; } doCombination(new StringBuilder(), combinations, digits); return combinations; } private void doCombination(StringBuilder prefix, List<String> combinations, final String digits) { if (prefix.length() == digits.length()) { combinations.add(prefix.toString()); return; } int curDigits = digits.charAt(prefix.length()) - '0'; String letters = KEYS[curDigits]; for (char c : letters.toCharArray()) { prefix.append(c); // 新增 doCombination(prefix, combinations, digits); prefix.deleteCharAt(prefix.length() - 1); // 刪除 } } }
這段是官網的
class Solution { Map<String, String> phone = new HashMap<>() {{ put("2", "abc"); put("3", "def"); put("4", "ghi"); put("5", "jkl"); put("6", "mno"); put("7", "pqrs"); put("8", "tuv"); put("9", "wxyz"); }}; List<String> output = new ArrayList<>(); public List<String> letterCombinations(String digits) { if (digits.length() != 0) backtrack("", digits); return output; } public void backtrack(String combination, String next_digits) { if (next_digits.length() == 0) { //如果傳進來的是空的,返回就是空的 output.add(combination); } else { //獲取傳進來的KEY,先獲取digits的第一個內容,分割出來 String digit = next_digits.substring(0, 1); //獲取對應的value String letters = phone.get(digit); for (int i = 0; i < letters.length(); i++) { //有value中有幾個字母就迴圈幾次,每次取出一個字母拼接起來 String letter = phone.get(digit).substring(i, i + 1); backtrack(combination + letter, next_digits.substring(1)); } } } }