17 Letter Combinations of a Phone Number
手機上每個數字按鈕旁邊都有3-4個字母,輸入數字字符串,輸出可能的字母組合。
例如輸入:”23”
輸出:[“ad”, “ae”, “af”, “bd”, “be”, “bf”, “cd”, “ce”, “cf”].
思路:建立每個數字和對應字母的映射關系。該個處理每一位數字,遍歷每個數字可能的取值。按照遞歸去實現很簡單。
private List<String> result =
new ArrayList<String>();
private static Map<Integer, List<Character>> numberMap =
new HashMap<Integer, List<Character>>();
static{
for(
int i=
2;i<
7;i++){numberMap.put(i,
new ArrayList<Character>());
for (
int j =
0; j <
3; j++) {
char ch = (
char) (
'a' +
3 * (i -
2) + j);numberMap.
get(i).add(ch);}}numberMap.put(
7,
new ArrayList<Character>());numberMap.
get(
7).add(
'p');numberMap.
get(
7).add(
'q');numberMap.
get(
7).add(
'r');numberMap.
get(
7).add(
's');numberMap.put(
8,
new ArrayList<Character>());numberMap.
get(
8).add(
't');numberMap.
get(
8).add(
'u');numberMap.
get(
8).add(
'v');numberMap.put(
9,
new ArrayList<Character>());numberMap.
get(
9).add(
'w');numberMap.
get(
9).add(
'x');numberMap.
get(
9).add(
'y');numberMap.
get(
9).add(
'z');}
public List<String>
letterCombinations(String digits) {result.clear();StringBuilder str =
new StringBuilder(digits.length());str.setLength(digits.length());
if(digits.length()>
0){robot(
0, digits, str);}
return result;
}
private void robot(
int idx, String digits, StringBuilder r) {
if (idx >= digits.length()) {result.add(r.toString());
return;}
int n = digits.charAt(idx) -
48;
if (n <
2)
return;
for(
char ch : numberMap.
get(n)){r.setCharAt(idx, ch);robot(idx +
1, digits, r);}
}
收獲1
嗯代碼夠丑的。看別人怎么處理映射關系。我怎么沒想到呢。之前也有這樣一個例子,當數字作為map的key的時候,選擇用數組代替map,可能會是一種比較優雅的方式。
String[] mapping =
new String[] {
"0",
"1",
"abc",
"def",
"ghi",
"jkl",
"mno",
"pqrs",
"tuv",
"wxyz"};
收獲2
一次性給stringBuider 一定的長度。這個做法在字符串中還是有點變扭。這個想法是從數組那里繼承過來的。可以使用字符串相加的方式。
private static final String[] KEYS = {
"",
"",
"abc",
"def",
"ghi",
"jkl",
"mno",
"pqrs",
"tuv",
"wxyz" };
private List<String> result =
new ArrayList<String>();
public List<String>
letterCombinations(String digits) {result.clear();robot(
0, digits,
"");
return result;
}
private void robot(
int idx, String digits, String prefix) {
if (idx >= digits.length()) {
if (prefix.length() >
0) {result.add(prefix);}
return;}
int n = digits.charAt(idx) -
48;
if (n <
2)
return;String letters = KEYS[n];
for (
int i =
0; i < letters.length(); i++) {robot(idx +
1, digits, prefix + letters.charAt(i));}
}
收獲3
我是沒法用遞推的方式實現的,只能用遞歸。看看別人怎么做。其實從上一個遞歸的代碼是可以得到一些啟示的。當然這是“馬后炮”的想法–看到別人這么做覺得應該想到的。但是之前我一直在用for去思考。
public List<
String> letterCombinations(
String digits) {LinkedList<
String> ans =
new LinkedList<
String>();
String[] mapping =
new String[] {
"0",
"1",
"abc",
"def",
"ghi",
"jkl",
"mno",
"pqrs",
"tuv",
"wxyz" };ans.add(
"");
for (
int i =
0; i < digits.length(); i++) {
int x = Character.getNumericValue(digits.charAt(i));
while (ans.peek().length() == i) {
String t = ans.remove();
for (char s : mapping[x].toCharArray())ans.add(t + s);}}return ans;}
參考鏈接
1 鏈接1
2 鏈接2
總結
以上是生活随笔為你收集整理的leetcode之回溯backtracing专题3的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。