难度中等
给定一个仅包含数字 2-9
的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
示例 1:
输入:digits = "23" 输出:["ad","ae","af","bd","be","bf","cd","ce","cf"]
示例 2:
输入:digits = "" 输出:[]
示例 3:
输入:digits = "2" 输出:["a","b","c"]
提示:
0 <= digits.length <= 4
digits[i]
是范围['2', '9']
的一个数字。
解法
老套路了,深度优先搜索,递归,从头到尾遍历。先拿个字符串数组存储一下这些电话号码的字母组合,数组下标对应的内容为 电话号码的字母,如 strs[2]="abc"。
然后写一个dfs函数,参数index是结果字符串的第几位,temp是记录结果字符串的内容 先写终止条件,index越界记录结果字符串,终止, 然后写递归的代码,以234为例,遍历abc 其中递归在遍历def 再嵌套递归遍历ghi 每次调用记得回溯,temp的最后一位加减字符。
事实证明,如果对某个字符的添加删除操作 最好还是用StringBuffer进行操作,很快, 之前用的temp+=‘a’ ,temp =temp.subString(0,length-1)是6ms 改成 temp.append(str.charAt(j)) ,temp.deleteCharAt(index); 之后是0ms。
str.substring也要最后赋值给str才行!
class Solution {
public static int dfs(List<String> ans,int index,String[] strs,String digits,int length,StringBuffer temp){
if(index==length){
ans.add(temp.toString());
return 0;
}
String str = strs[digits.charAt(index)-'0'];
int ilength=strs[digits.charAt(index)-'0'].length();
for(int j=0;j<ilength;j++)
{
temp.append(str.charAt(j));
dfs(ans, index + 1, strs, digits, length, temp);
temp.deleteCharAt(index);
}
return 0;
}
public static List<String> letterCombinations(String digits) {
List<String> ans = new ArrayList();
if(digits.length()==0){
return ans;
}
String[] strs = {"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
int length = digits.length();
dfs(ans,0,strs,digits,length,new StringBuffer());
return ans;
}
}
其他解法
有的用Map来存储数字对应的字母,有的不存储,直接用数学去算数字对应的字母。都可以试试。