给定一个仅包含数字 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'] 的一个数字。
3. 解法:
算法思路:
每个位置可选择的字符与其他位置并不冲突,因此不需要标记已经出现的字符,只需要将每个数字对应的字符依次填入字符串中进行递归,在回溯是撤销填入操作即可。
| • | 在递归之前我们需要定义一个字典 phoneMap,记录 2~9 各自对应的字符。 |
递归函数设计:void backtrack(unordered_map<char, string>& phoneMap, string& digits, int
index)
参数:index (已经处理的元素个数),ans (字符串当前状态),res (所有成立的字符串);
返回值:无
函数作用:查找所有合理的字母组合并存储在答案列表中。
递归函数流程如下:
1. 递归结束条件:当 index 等于 digits 的长度时,将 ans 加入到 res 中并返回;
2. 取出当前处理的数字 digit,根据 phoneMap 取出对应的字母列表 letters;
3. 遍历字母列表 letters,将当前字母加入到组合字符串 ans 的末尾,然后递归处理下一个数字(传入 index + 1,表示处理下一个数字);
4. 递归处理结束后,将加入的字母从 ans 的末尾删除,表示回溯。
5. 最终返回 res 即可。
Java算法代码:
class Solution {
String[] hash = {"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
List<String> ret;
StringBuffer path;
public List<String> letterCombinations(String digits) {
ret = new ArrayList<>();
path = new StringBuffer();
if(digits.length() == 0)
return ret;
dfs(digits,0);
return ret;
}
public void dfs(String digits, int pos) {
if(pos == digits.length()){
ret.add(path.toString());
return ;
}
String cur = hash[digits.charAt(pos) - '0'];
for(int i = 0 ; i < cur.length();i++){
path.append(cur.charAt(i));
dfs(digits,pos+1);
path.deleteCharAt(path.length() - 1);
}
}
}
运行结果:

递归展开:

逻辑展开:

代码中的每一处出现都是有原因的。不然不会在哪里。
---------------------------------------------------------------------------------------------------------------------------------
记住,相信你的递归函数,它可以做到!
记住,不理解时候,去尝试手动展开!
记住,逻辑展开(你不可能对所有的题目都进行手动展开)!
电话号码字母组合的算法求解
897

被折叠的 条评论
为什么被折叠?



