原题链接:17. 电话号码的字母组合
解题思路:
- 假设输入是
'23'
,那么就需要在'2'
对应的字母映射'abc'
中分别选取一个。再以此为基础,从'3'
对应的字母映射'def'
中选取一个,组合成最终结果。 - 由于输入的数字并不确定长度,因此选择用递归的方式遍历
digits
。 - 每层递归处理的都通过参数
current
,选择当前需要处理的字母映射。 - 在递归中利用
for
循环遍历字母映射,逐个完成对字母的选中,之后下探到下层递归,处理下一个数字。
/**
* @param {string} digits
* @return {string[]}
*/
var letterCombinations = function (digits) {
// 如果传入digits为空,则直接返回结果[]
if (!digits || !digits.length) {
return [];
}
// 使用Map存储按键对应的字母
const map = new Map([
['2', 'abc'],
['3', 'def'],
['4', 'ghi'],
['5', 'jkl'],
['6', 'mno'],
['7', 'pqrs'],
['8', 'tuv'],
['9', 'wxyz'],
]);
// 存储最终结果
let result = [];
// 回溯生成所有的字符串组合
function backtrack(str, current) {
// 递归终止条件
// 当生成的字符串长度等于输入长度时,表示生成完毕,储存结果并退出循环。
// 若不退出,由于current已经超出了digits长度,会因map.get获取值为空而报错。
if (str.length === digits.length) {
result.push(str);
return;
}
// 当前层递归逻辑
// 从Map中获取当前输入的数字映射的字母
const digit = map.get(digits[current]);
// 遍历当前映射的字符串,生成不同组合
for (let i = 0; i < digit.length; i++) {
// 下探到下层递归
// 在当前字符串中选取一个字母,进入下一层递归的选择
backtrack(str + digit[i], current + 1);
}
}
// 回溯生成组合,初始状态str为空,current为0
backtrack('', 0);
return result;
};