给定一个仅包含数字 2-9
的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
回溯
时间复杂度:O(m^n),m 是每个数字对应的字母组合的平均长度,n是digits长度。
这个递归写的很牛逼,很值得学习 。
class Solution {
public List<String> letterCombinations(String digits) {
List<String> combinations = new ArrayList<String>();
//创建字符串列表
if (digits.length() == 0) {
return combinations;
}//输入字符串为空,直接返回空列表
Map<Character, String> phoneMap = new HashMap<Character, String>() {{
put('2', "abc");
put('3', "def");
put('4', "ghi");
put('5', "jkl");
put('6', "mno");
put('7', "pqrs");
put('8', "tuv");
put('9', "wxyz");
}};
//创建数字到字符串的映射关系
backtrack(combinations, phoneMap, digits, 0, new StringBuffer());
//回溯
return combinations;
}
public void backtrack(List<String> combinations, Map<Character, String> phoneMap,
String digits, int index, StringBuffer combination) {
if (index == digits.length()) {
//满足条件,递归返回
//第一次调用不会进入if语句中
combinations.add(combination.toString());
} else {
char digit = digits.charAt(index);
//获得第index+1个字符
String letters = phoneMap.get(digit);
//获得第index+1个字符对应的字符串
int lettersCount = letters.length();
//获得第index+1个字符对应的字符串的长度
for (int i = 0; i < lettersCount; i++) {
combination.append(letters.charAt(i));
//将第i+1个字符添加到combination中
backtrack(combinations, phoneMap, digits, index + 1, combination);
//递归进去,直到满足if条件,获得一个完整的combination加入到combinations中
combination.deleteCharAt(index);
//一个一个递归返回,删除combination的每个字符,以便进行下一次for循环
}
}
}
}
补:
组合for循环中递归
List<String> res = new ArrayList<>();
StringBuffer temp = new StringBuffer();
public List<String> letterCombinations(String digits){
if(digits.length() == 0) return res;
// 将digits中的数字映射为字母组
String[] numString = {"", "", "abc", "def","ghi", "gkl", "mno", "pqrs", "tuv", "wxyz"};
backtrace(digits, numString, 0);
return res;
}
public void backtrace(String digits, String[] numString, int num){
// num记录temp当前长度
// num记录递归到digits的哪一位
if(num == digits.length()) {
res.add(temp.toString());
return;
}
// 获取str映射的字母组
String str = numString[digits.charAt(num) - '0'];
// 遍历str,每次遍历使用不同的str
// 因为要获取abc、def两组字母的所有组合,所以要遍历abc(def)。把i<length设置成字幕组的长度
for(int i = 0; i < str.length(); i++){
temp.append(str.charAt(i));
backtrace(digits, numString, i+1);
temp.deleteCharAt(temp.length() - 1);
}
}