电话号码的字母组合

LeetCode每日一题,17. Letter Combinations of a Phone Number

先看题目描述

大意就是手机上的数字与字母对应,给出只含数字的字符串,让我们返回对应字母的排列组合

算法与思路

一开始的思路是模拟数字一个个的添加进来,先是添加 2 对应的,于是 res 中就有 [“a”, “b”, “c”],然后将 3 添加进来,因为 3 对应 3 个字母,先将 res * 3 变为 [“a”, “b”, “c”, “a”, “b”, “c”, “a”, “b”, “c”],然后分别添加 3 个 “d”,3 个 “e”,3 个 “f”,res 变为 [“ad”, “bd”, “cd”, “ae”, “be”, “ce”, “af”, “bf”, “cf”],然后返回 res 即可,就用代码模拟这个过程

算法源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import java.util.*;

class Solution {
public List<String> letterCombinations(String digits) {
List<String> res = new LinkedList<>();
if (digits.length() == 0) return res;
res.add("");
HashMap<Character, String> phone = new HashMap<>();
phone.put('2', "abc");
phone.put('3', "def");
phone.put('4', "ghi");
phone.put('5', "jkl");
phone.put('6', "mno");
phone.put('7', "pqrs");
phone.put('8', "tuv");
phone.put('9', "wxyz");
for (char c: digits.toCharArray()) {
int cur = 0;
int coun = res.size();
int len = phone.get(c).length();
for (int i = 1; i < len; i++) {
for (int j = 0; j < coun; j++) {
res.add(res.get(j));
}
}
for (int i = 0; i < len; i++) {
for (int j = 0; j < coun; j++) {
res.set(cur, res.get(cur) + phone.get(c).charAt(i));
cur++;
}
}
}
return res;
}
}

但这个代码的运行效率不行,后来看了题解才发现可以用回溯,且频繁的字符串组装可以使用 StringBuilder 下面是使用回溯和 StringBuilder 的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import java.util.*;

class Solution {
private List<String> res = new LinkedList<>();
private String letterMap[] = {
" ", //0
"", //1
"abc", //2
"def", //3
"ghi", //4
"jkl", //5
"mno", //6
"pqrs", //7
"tuv", //8
"wxyz" //9
};

public List<String> letterCombinations(String digits) {
if (digits.length() == 0) return res;
StringBuilder sb = new StringBuilder();
combination(digits, 0, sb);
return res;
}

private void combination(String digits, int index, StringBuilder sb) {
if (index == digits.length()) {
res.add(sb.toString());
return;
}
Character c = digits.charAt(index);
String letters = letterMap[c - '0'];
for (int i = 0; i < letters.length(); i++) {
combination(digits, index + 1, sb.append(letters.charAt(i)));
sb.deleteCharAt(sb.length() - 1);
}
}
}