给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。

示例 1:
输入: digits = "23"
输出:["ad","ae","af","bd","be","bf","cd","ce","cf"]
示例 2:
输入: digits = ""
输出:[]
示例 3:
输入: digits = "2"
输出:["a","b","c"]
解题思路:
1.回溯
这道题是一道很经典的回溯算法题,只要将输入的数字转换成字符串然后再进行排列组合即可得出答案。
java
public class LetterCombinations {
private static final String[] PHONE_MAP = {
"", // 0
"", // 1
"abc", // 2
"def", // 3
"ghi", // 4
"jkl", // 5
"mno", // 6
"pqrs", // 7
"tuv", // 8
"wxyz" // 9
};
//存储组合结果
private List<String> result;
//存储临时字符串组合结果
private StringBuilder temp;
public List<String> LetterCombinations(String digits) {
result = new ArrayList<>();
temp = new StringBuilder();
if (digits == null || digits.length() == 0) {
return result;
}
//从0下标开始遍历
backtrack(digits, 0);
return result;
}
private void backtrack(String digits, int index) {
//设置终止条件
if(digits.length() == index){
//将临时变量添加到结果集和中
result.add(temp.toString());
return;
}
char digitsChar = digits.charAt(index);
int phoneIndex = digitsChar - '0';
//取出当前号码的字母组合
String letters = PHONE_MAP[phoneIndex];
for (char c : letters.toCharArray()) {
//添加当前字符
temp.append(c);
//递归处理下一个数字
backtrack(digits,index+1);
//回溯,删除最后一个加入的字符,尝试进入下一轮递归
temp.deleteCharAt(temp.length()-1);
}
}
public static void main(String[] args) {
LetterCombinations letterCombinations = new LetterCombinations();
System.out.println("输入23 获取结果: "+letterCombinations.LetterCombinations("23"));
System.out.println("输入232 获取结果: "+letterCombinations.LetterCombinations("232"));
}
}
2.队列
借助队列实现数据的层级遍历
实现思路:
以输入23为例
null //空值
/ l \
a b c //将2对应的字符(abc)加入到队列中
/ l \ / l \ / l \
ad ae af bd be bf cd ce cf //将3对应的字符(def)加入队列中
java
public class LetterCombinations1 {
private static final String[] PHONE_MAP = {
"", // 0
"", // 1
"abc", // 2
"def", // 3
"ghi", // 4
"jkl", // 5
"mno", // 6
"pqrs", // 7
"tuv", // 8
"wxyz" // 9
};
public List<String> LetterCombinations(String digits) {
List<String> result = new ArrayList<>();
//判断边界值
if (digits == null || digits.length() == 0) {
return result;
}
//将第一个数字对应的字符加入到队列中
char[] charFirst = PHONE_MAP[digits.charAt(0) - '0'].toCharArray();
for (char c : charFirst) {
queue.offer(String.valueOf(c));
}
//排列组合剩下的字符
for (int i = 1; i < digits.length(); i++) {
//获取需要添加的字符串
String string = PHONE_MAP[digits.charAt(i) - '0'];
//当前队列节点的个数
int size = queue.size();
for (int j = 0; j < size; j++) {
String poll = queue.poll();
//将之前已经组装的字符串与当前的字符进行排列组合
for (char c : string.toCharArray()) {
queue.offer(poll+c);
}
}
}
result.addAll(queue);
return result;
}
// 测试用例
public static void main(String[] args) {
LetterCombinations1 letterCombinations = new LetterCombinations1();
System.out.println("输入23 获取结果: "+letterCombinations.LetterCombinations("23"));
System.out.println("输入232 获取结果: "+letterCombinations.LetterCombinations("232"));
}
}