这是我参与11月更文挑战的第19天,活动详情查看:2021最后一次更文挑战
题目
给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
示例 1:
输入:digits = "23"
输出:["ad","ae","af","bd","be","bf","cd","ce","cf"]
示例 2:
输入:digits = ""
输出:[]
思路
题目要找的是一个全集,所以必然需要穷举出所有组合
首先,使用哈希结构映射每个数字可能对应的字母,方便后续处理
-
考虑一个最简单的情况,当字符的长度为1时,只需要遍历该数字对应哈希结构里可能的字母,放入结果中即可
-
再考虑字符长度为2时:
23,先考虑字符第一位数字2,它可能代表的字母为:a、b、c,但是此时,无法将a、b、c每个直接放入结果数组中,因为后面还有数字3。那么此时可以把问题分解为求:a3,b3,c3,可能代表的数字组合,这样是不是就回到了处理一个字符的情况呢,只不过前面多了一个已存在的字符str -
那么是不是可以这样做,我们每次只处理一个数字,将该数字可能代表的字母穷举,然后将穷举的结果分别拼接上一部处理得到的字母串,此时得到已处理的数字代表的
字母串,然后再处理后一位数字;当处理到最后一个数字时,每个组合形成的字符串,就是这些数字可能代表的字母组合中的一种,把它放入结果数组中,即可得到答案
代码如下
/**
* @param {string} digits
* @return {string[]}
*/
var letterCombinations = function(digits) {
if(digits === '') return [];
// 哈希结构,映射数字对应的字母串
const map = {
"2": "abc",
"3": "def",
"4": "ghi",
"5": "jkl",
"6": "mno",
"7": "pqrs",
"8": "tuv",
"9": "wxyz"
}
let quene = [], n = digits.length;
// 处理第i个位置上的数字
const dfs = (crtStr, i) => {
// 当处理到最后一个的时候,即是可能的组合
if(i >= n) {
quene.push(crtStr);
return;
}
// 该数字可能代表的字母串
let letters = map[digits.charAt(i)];
// 遍历字母串,拼接之前的字母串,再次调用处理函数
for(let j = 0; j < letters.length; j++) {
dfs(crtStr + letters.charAt(j), i + 1);
}
}
// 启动,先处理第一个位置上的数字
dfs('', 0);
return quene;
}
小结
上述算法也称为回溯,回溯算法回溯算法实际上一个类似枚举的搜索尝试过程,主要是在搜索尝试过程中寻找问题的解,当发现已不满足求解条件时,就“回溯”返回,尝试别的路径。
LeetCode 👉 HOT 100 👉 电话号码的字母组合 - 中等题 ✅
LeetCode 👉 HOT 100 👉 三数之和 - 中等题 ✅
LeetCode 👉 HOT 100 👉 盛最多水的容器 - 中等题 ✅
LeetCode 👉 HOT 100 👉 最长回文子串 - 中等题 ✅
LeetCode 👉 HOT 100 👉 无重复字符的最长子串 - 中等题 ✅