「这是我参与2022首次更文挑战的第9天,活动详情查看:2022首次更文挑战」。
题目描述
给定一个仅包含数字 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'] 的一个数字。
题目链接:[电话号码的字母组合](leetcode-cn.com/problems/3s…)
思路介绍
这道题目是典型的回溯问题。再具体一点,它是典型的排列组合类问题,通常都需要使用回溯的思想去处理。
回溯过程中维护一个字符串,表示已有的字母排列(如果未遍历完电话号码的所有数字,则已有的字母排列是不完整的)。该字符串初始为空。每次取电话号码的一位数字,从哈希表中获得该数字对应的所有可能的字母,并将其中的一个字母插入到已有的字母排列后面,然后继续处理电话号码的后一位数字,直到处理完电话号码中的所有数字,即得到一个完整的字母排列。然后进行回退操作,遍历其余的字母排列。 两个注意事项
前进和后退的状态变化和恢复 寻找递归结束条件
分别根据当前位置的数是几来进行回溯构造字母组合,按键中的值先存在数组中方便取值。 使用到的数据结构的解释如下: ans 存储结果的列表 phone 存储电话按键对应位置的字母String数组,因为数组索引的原因,为了方便根据索引取值,直接将0和1位置的元素置为空串。
代码
class Solution {
List<String> ans = new ArrayList<>();
String[] phone = new String[]{"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
public List<String> letterCombinations(String digits) {
if("".equals(digits)) return ans;
dfs(digits, 0, new StringBuilder());
return ans;
}
public void dfs(String digits, int start, StringBuilder sb){
if(start == digits.length()){
ans.add(new String(sb));
return;
}
// 取出当前数字
int curIdx = digits.charAt(start) - '0';
// 当前数字对应的电话按键
String curPhoneNum = phone[curIdx];
// 回溯
for(int i = 0; i < curPhoneNum.length(); i++){
sb.append(curPhoneNum.charAt(i));
dfs(digits, start + 1, sb);
sb.deleteCharAt(sb.length() - 1);
}
}
}
运行结果
执行结果:
通过
执行用时:0 ms
内存消耗:37.4 MB
时间复杂度:O(2^len(s)) 空间复杂度:O(len(s));
\