「这是我参与11月更文挑战的第16天,活动详情查看:2021最后一次更文挑战」
电话号码的数字组合
给定一个仅包含数字 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 <= 4digits[i]是范围['2', '9']的一个数字。
解法
首先在考虑到数字和字母映射问题的时候,我们应该考虑到使用map结构,将数字和对应字母字符串建立起映射,而对于这种暴力解法是很多层的for循环的问题,我们可以考虑回溯法,主要思路如下:
- 将数字和对应字母字符串存入map
- 递归函数里传入当前已经构建好的字符串,和当前构建的字符的index,用以判断递归是否完成
- 在构建字符串的过程中,先取出digits数组字符串中当前次序的数字对应的字符串,根据字符串的个数,依次创建不同的分支,拼接下一个字符串,重复这一操作,直到当前构建的字符的index大于digits.length - 1,也就是当前分支的字符串构建完毕,将构建的字符串压入结果数组,终止当前分支的递归操作
var letterCombinations = function(digits) {
let res = [];
// 如果传入的数字字符串长度为空,返回空的res
if (digits.length === 0) return res;
let map = new Map([
['2', 'abc'],
['3', 'def'],
['4', 'ghi'],
['5', 'jkl'],
['6', 'mno'],
['7', 'pqrs'],
['8', 'tuv'],
['9', 'wxyz']
])
const dfs = function(str, i) {
// 当前递归分支已经递归到了最后一层,即已经拼接了digits.length字符串
if (i > digits.length - 1) {
// 将这个分支的解,推入结果数组
res.push(str);
// 结束当前递归分支
return;
}
// 获取当前数字对应的字母数组
let letterStr = map.get(digits[i]);
// 一个字母是一个选择,对应一个递归分支
for (let letter of letterStr) {
// 选择翻译成letter,生成新字符串,i指针右移继续翻译(递归)
dfs(str + letter, i + 1);
}
}
dfs("", 0);
return res;
};