题目
给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
示例: 输入:“23” 输出:[“ad”, “ae”, “af”, “bd”, “be”, “bf”, “cd”, “ce”, “cf”].
说明:尽管上面的答案是按字典序排列的,但是你可以任意选择答案输出的顺序。
思路
传统思路,输入“2,3”,会想到用两层for循环,进行组合,但是需要用回溯来解决n个for循环的问题,转化成树形问题
数字和字母如何映射: 可以通过创建一个二维数组或者map来做映射
回溯三部曲:
- 确定回溯函数参数:首先需要一个字符串记录手机叶子结点的结果,另外需要一个字符串数组result将所有的结果全部保存起来,参数为给定的字符串数字string digits以及int类型的index,用来记录遍历到第几个数字了,同时也是树的深度
- 确认终止条件:比如输入‘2,3’,两个数字只需要向下递归两层即可,叶子结点就是要收集的结果集,终止条件即为index == 输入数字的个数
- 确定单层遍历逻辑:首先要取index指向的数字,并找到对应的字符集(映射)然后用for循环来处理这个字符集
java代码如下:
class Solution {
List<String> list = new ArrayList<>();//设置全局列表存储最后的结果
public List<String> letterCombinations(String digits){
if(digits == null || digits.length() == 0){
return list;
}
//初始对应所有的数字,为了直接对应2-9,新增了两个无效的字符串""
String[] numString ={"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
backTracking(digits,numString,0);
return list;
}
//每次迭代获取一个字符串,所以会设计大量的字符串拼接,所以这里选择更为高效的 StringBuilder
StringBuilder temp = new StringBuilder();
//比如digits如果为"23",index为0,则str表示2,对应 abc
public void backTracking(String digits,String[] numString,int index){
if(index == digits.length()){//终止条件
list.add(temp.toString());//StringBuilder需要转换为String类型
return;
}
//str表示当前index对应的字符串
String str = numString[digits.charAt(index) - '0'];
for(int i = 0; i < str.length(); i++){//for循环横向遍历
temp.append(str.charAt(i));
backTracking(digits,numString,index+1);//递归纵向遍历
temp.deleteCharAt(temp.length() - 1);//回溯不断调整结果集
}
}
}