给定一个仅包含数字 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']
的一个数字。
思路
这题还是比较简单的一道DFS搜索题,但还是因为脑子糊涂卡了一个晚上(这里建议如果卡了一个晚上还没做出来,干脆第二天醒来在草稿纸上圈圈画画再写,脑袋清醒之后逻辑清楚,还是很容易AC的)。
主要思路就是先建立一个字符串数组map
,下标对应着手机九键上的几个字母,比如下标2
对应"abc"
,下标3
对应"def"
……这样的话,每次读取输入的字符串中的某一位,就可以知道它能够对应着哪几个字母。
然后就是DFS搜索了:
递归边界:当输入字符串已经读完的时候(digitsIndex==digits.length()-1
,这里我用digitsIndex
来记录正在读取当前位置,从0~digits.length()-1
),将暂时存储结果的sBuffer
里的内容交给answear
,然后return
即可。
递归条件:当下一位索引仍然合法时(即:nextDigitsIndex<=digits.length()-1
),搜索下一位所有可能对应的字母,因为有些数字是对应3个字母,有些数字对应4个字母,因此,在写for循环的时候,不能将i的上限写死,我这里写了i<map[nextNumber].length()
,这样的话,就是正好遍历下一位数字对应的所有字母。
然后是要注意的地方:
- 每次DFS搜索完之后,都要退出
sBuffer
的最后一位,这个过程类似于数学的排列组合,比如输入"23"
,我们会先选a
,再选d
,这样就有了一种结果"ad"
。选完d
之后DFS搜索到边界,退出,因此我们会去掉d
,选择e
,此时又有了另外一种结果"ae"
,以此类推。所以,我们每次搜索完毕之后,都要删除最后一位。 - 在第一次进行DFS时也要写for循环,否则的话,假如还是输入
"23"
,我们就只能得到由a
开头的几种组合,因为我们没有对第一位所对应的字母进行遍历。
代码
public class Solution {
String[] map = {"_", "!@#", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
List<String> answear = new ArrayList<String>();
StringBuffer sBuffer = new StringBuffer();
public void dfs(int digitsIndex, int mapIndex, String digits) {
int number = digits.charAt(digitsIndex)-'0';
sBuffer.append(map[number].charAt(mapIndex));
if(digitsIndex==digits.length()-1) {
String temp = sBuffer.toString();
answear.add(temp);
return;
}
int nextDigitsIndex = digitsIndex+1;
if(nextDigitsIndex<=digits.length()-1) {
int nextNumber = digits.charAt(nextDigitsIndex)-'0';
for(int i=0;i<map[nextNumber].length();i++) {
dfs(nextDigitsIndex, i, digits);
sBuffer.delete(sBuffer.length()-1, sBuffer.length());
}
}
}
public List<String> letterCombinations(String digits){
if(digits.length()!=0) {
int number = digits.charAt(0)-'0';
for(int i=0;i<map[number].length();i++){
dfs(0, i, digits);
sBuffer.delete(sBuffer.length()-1, sBuffer.length());
}
}
return answear;
}
}