題目描述
給定一個僅包含數字 2-9
的字符串,返回全部它能表示的字母組合。java
給出數字到字母的映射以下(與電話按鍵相同)。注意 1 不對應任何字母。git
示例:算法
輸入:"23" 輸出:["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].
說明: 儘管上面的答案是按字典序排列的,可是你能夠任意選擇答案輸出的順序。數組
解題思路
回溯法
首先用一個數組把每一個數字按鍵對應的字母存儲起來,再把給定的字符串digits
拆分紅每個單獨的數字作處理。使用一個輔助函數進行處理app
private void helper (String digits, int i, StringBuilder cur, List<String> ans); /* String digits : 給定的數字組合字符串 int i :當前(遞歸)處理的層數 StringBuilder cur :當前字母組合 List<String> ans :結果列表 */
處理過程以下:函數
- 取出當前數字,以及該數字按鍵對應的字母,存爲一個
char
數組curLetters
- 對
curLetters
進行遍歷,將當前字符加入當前字母組合cur
,而後(遞歸地)處理後一個數字 - 當層數等於給定字符串
digits
長度時,將當前字母組合cur
加入結果列表ans
,刪除剛用過的字符(也就是當前字母組合的最後一個字母) - 遍歷完成後,結果列表
ans
就是題目要求的結果
Java 實現
private final static String[] digitsToChars = {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"}; public List<String> letterCombinations (String digits) { List<String> ans = new ArrayList<>(); if (digits.length() == 0) return ans; helper(digits, 0, new StringBuilder(), ans); return ans; } private void helper (String digits, int i, StringBuilder cur, List<String> ans) { if (digits.length() == i) { ans.add(cur.toString()); } else { int digit = Character.getNumericValue(digits.charAt(i)); // 當前考察的數字 char[] curLetters = digitsToChars[digit].toCharArray(); // 當前考察的數字對應的字母集合 for (char c : curLetters) { cur.append(c); helper(digits, i + 1, cur, ans); cur.deleteCharAt(i); // 回溯:刪掉剛纔用過的字母 } } }
心得體會
刷探索卡片第一次遇到用回溯算法的題目,這一題中,回溯算法就體如今湊齊了digits.length()
長度的字符串後,要往回刪一個字符,方便進行新的字母組合。ui