题目描述
给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
示例
题解
使用回溯,用递归控制for循环嵌套的数量!
代码
class Solution {
String digits;
String[] models = new String[]{"abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
List<String> res = new ArrayList<>();
public List<String> letterCombinations(String digits) {
if (digits == null || digits.isEmpty()) {
return res;
}
this.digits = digits;
// StringBuilder提高效率
deep(new StringBuilder(), 0);
return res;
}
public void deep(StringBuilder now, int thisNum) {
// 如果数字已遍历完毕,存储结果后返回
if (thisNum == digits.length()) {
res.add(new String(now));
return;
}
if (thisNum > digits.length()) {
return;
}
// 获取这次要遍历的字符组A
String thisModel = models[digits.charAt(thisNum) - '0' - 2];
for (int i = 0; i < thisModel.length(); i++) {
// 加入字符
now.append(thisModel.charAt(i));
// 继续遍历下一组字符B
deep(now, 1 + thisNum);
// 删除本次的字符,继续字符组A的遍历
now.deleteCharAt(thisNum);
}
}
}
性能
注意点
当不确定for循环执行几次时,可以使用回溯方法。回溯模板如下:
void dfs()//参数用来表示状态
{
if(到达终点状态)
{
...//根据题意添加
return;
}
if(越界或者是不合法状态) //剪枝
return;
for(扩展方式)
{
if(扩展方式所达到状态合法)
{
修改操作; //根据题意来添加
标记;
if(越界或者是不合法状态) //剪枝
return;
dfs();
还原标记,例如记录和还原深度遍历的路径等等;
}
}
}