电话号码的字母组合
1.问题描述
给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。

示例:
输入:"23"
输出:["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].
说明:
尽管上面的答案是按字典序排列的,但是你可以任意选择答案输出的顺序。
2.求解
回溯解法
回溯法是从根结点出发,以深度优先的方式搜索的一种算法。
-
首先使用哈希表存储每个数字对应的所有可能的字母,然后进行回溯操作。
-
每次取电话号码的一位数字,将其中的一个字母插入到字符串后面,然后继续处理下一位数字,一直到数字处理完成。
-
此时便拿到了一个完整的字符串组合,然后进行回退操作,遍历其余的字母序列。
本题中需要在循环中嵌套递归调用。
代码如下
List<String> list = new ArrayList<>();
String[] letter_map = {" ", "*", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
public List<String> letterCombinations(String digits) {
if (digits == null || digits.length() == 0) {
return list;
}
iterStr(digits, new StringBuilder(), 0);
return list;
}
void iterStr(String digits, StringBuilder stringBuilder, int index) {
if (index == digits.length()) {
list.add(stringBuilder.toString());
return;
}
char c = digits.charAt(index);
int num = c - '0';
String s = letter_map[num];
for (int i = 0; i < s.length(); i++) {
stringBuilder.append(s.charAt(i));
iterStr(digits, stringBuilder, index+1);
stringBuilder.deleteCharAt(stringBuilder.length() - 1);
}
}
- 时间复杂度为遍历字母组合的总数为O(3m×4n),其中m 是输入中对应 33 个字母的数字个数(包括数字 22、33、44、55、66、88),nn 是输入中对应 44 个字母的数字个数(包括数字 77、99)。
- 空间复杂度O(m + n),即输入数字的总个数。
几个小知识点
队列解法
利用队列先进先出,将之前的字符串出队,拼接新的字符,新生成的字符串入队。
代码如下
public List<String> letterCombinations(String digits) {
LinkedList<String> ans = new LinkedList<String>();
if (digits.isEmpty()) return ans;
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;
}
-
likList.peek方法
该方法返回头对象或元素(即,它返回列表中唯一的第一个元素)。 如果列表为空,则不会给出任何异常。

给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。
浙公网安备 33010602011771号