来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/letter-combinations-of-a-phone-number
给定一个仅包含数字 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'] 的一个数字。
答案:
class Solution {
// 数字到号码的映射
private String[] map = {"abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
// 路径
private StringBuilder sb = new StringBuilder();
// 结果集
private List<String> res = new ArrayList<>();
public List<String> letterCombinations(String digits) {
if(digits == null || digits.length() == 0) return res;
backtrack(digits,0);
return res;
}
// 回溯函数
private void backtrack(String digits,int index) {
if(sb.length() == digits.length()) {
res.add(sb.toString());
return;
}
String val = map[digits.charAt(index)-'2'];
for(char ch:val.toCharArray()) {
sb.append(ch);
backtrack(digits,index+1);
sb.deleteCharAt(sb.length()-1);
}
}
}
思路:
我们看到这道题首先最简单暴力的方法就是遍历了,但是有个问题就是我们不知道要用几个for,遇到这种不知道几个for能解决的问题,果断就用回溯,也就是回调函数的方式处理
首先我们是需要一个有所有按键字母的一个集合,所以使用了一个数组来表示
然后当输入的字符串为空必然就是不正常的,直接返回即可
进入回溯方法,例如输入 234,那么当然字母三个作为一个组合记录下来,所以下面的代码就是这个意思
if(sb.length() == digits.length())
- index默认为0,也就是从第一个号码的字母取,首先我们的号码从题中可以知道是从2开始的,所以要取得字母数组中的下标,当然就是 index-2,首先digits.charAt(index),当index 为0的时候取的是第一个号码的值,当index为1就是取第二个号码的值,用这个值减去'2'就取得了当前号码对应的字母组合了,这一点如果不懂就不妨随便写一个号码,然后对应着程序走一下就懂了。
String val = map[digits.charAt(index)-'2'];
- 下面代码就是核心了,遍历字母组合,例如234,首先遍历2对应的字母组合 abc,b.append(ch),把a添加进去之后就要匹配a开头的剩余两个字母了,这个时候进行回调函数,什么时候结束呢,就是长度跟号码长度一致就返回
for(char ch:val.toCharArray()) {
sb.append(ch);
backtrack(digits,index+1);
sb.deleteCharAt(sb.length()-1);
}
- 最后这个就是切换字母,例如 234,字母aeh拿到了,如果要下一个不得先把h给拿掉,然后继续吗?
sb.deleteCharAt(sb.length()-1);