题目
给定一个仅包含数字 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']的一个数字。
思路
- 暴力解法最多需要写四重循环时间复杂度太高,于是考虑空间换时间
- 空间换时间,可以考虑1使用map存储,2使用递归
- 递归遍历输入字符串的时候只需要对递归函数传入数字对应的索引,通过 索引+1 实现递归
- 对给定输入字符串"2345",可以递归计算每一个数字,在递归每一个数字的时候,for循环遍历该数字代表的字符
- 维护一个用来组合某一种可能性的组合(即数组),每次一条递归链条结束的时候,将将组合中的数据pop一个,即将组合数组进行清理,以便下次循环递归(回溯的时候再push新的数据)的时候使用。
- 空间换时间,可以考虑1使用map存储,2使用递归
代码
/**
* @param {string} digits
* @return {string[]}
*/
var letterCombinations = function(digits) {
let n = digits.length;
if (n === 0) return [];
let map = {
"2": "abc",
"3": "def",
"4": "ghi",
"5": "jkl",
"6": "mno",
"7": "pqrs",
"8": "tuv",
"9": "wxyz",
}
let combinations = [];
let combination = [];
const backtrack = (index) => {
if (index === n) {
combinations.push(combination.join(""));
} else {
let digit = digits[index];
for (let key in map[digit]) {
if (map[digit].hasOwnProperty(key)) { // 确保只遍历自身的属性
combination.push(map[digit].charAt(key));
backtrack(index + 1)
combination.pop()
}
}
}
}
backtrack(0);
return combinations;
};