经典的backtracking(回溯算法)的题目。当一个题目,存在各种满足条件的组合,并且需要把它们全部列出来时,就可以考虑backtracking了。当然,backtracking在一定程度上属于穷举,所以当数据特别大的时候,不合适。而对于那些题目,可能就需要通过动态规划来完成。
这道题的思路很简单,假设输入的是"23",2对应的是"abc",3对应的是"edf",那么我们在递归时,先确定2对应的其中一个字母(假设是a),然后进入下一层,穷举3对应的所有字母,并组合起来("ae","ad","af"),当"edf"穷举完后,返回上一层,更新字母b,再重新进入下一层。这个就是backtracing的基本思想。
递归代码如下:
class Solution {
public List<String> letterCombinations(String digits) {
// String digitletter[] = {"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
String[] table = {"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
List<String> res = new ArrayList<String>();
// char [] dig=digits.toCharArry();
core(digits,table,0,"",res);//从第0层开始,当前字符串为"";
return res;
}
public static void core(String digits,String[] table, int layer, String cur, List<String> res)
{
//最后一层,准备返回
//1、第一步,返回条件
if(layer==digits.length())
{
if(cur!="") res.add(cur);
// else return;//必须返回,不是 否则 返回。
return;
}
String temp=table[digits.charAt(layer)-'0'];
for(int i=0;i<temp.length();i++)//2、遍历每一层的一个字母
{
// cur+=temp.charAt(i);//这样写是错误的哦
String next=cur+temp.charAt(i);//3、返回后,遍历每一层的每一个字母;
core(digits,table,layer+1,next,res);//4、layer+1进入下一层
}
}
用循环实现:
class Solution {
private static final String[] DICTIONARY = {
" ",
"",
"abc",
"def",
"ghi",
"jkl",
"mno",
"pqrs",
"tuv",
"wxyz",
};
static List<String> res = new ArrayList<>();
public List<String> letterCombinations(String digits) {
if(digits == null || digits.equals("")){
return res;
}
res.clear();
doCombination(digits, 0, "");
return res;
}
private void doCombination(String digits, int index, String s) {
if(index == digits.length()){
res.add(s);
return;
}
char current = digits.charAt(index);
String tmp = DICTIONARY[current - '0'];
for(int i = 0; i < tmp.length(); i++){
doCombination(digits, index + 1, s + tmp.charAt(i));
}
}
}