携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第21天,点击查看活动详情
电话号码的字母组合
给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。2对应abc,3对应def,4对应ghi,5对应jkl,6对应mno,7对应pqrs,8对应tuv,9对应wxyz
来源:力扣(LeetCode) 链接:leetcode.cn/problems/le…
分析
回溯
- 使用对象存储数字对应的字母,结果是字符串数组,在获得字符串的时候,遍历电话号码的每一位,从对象中获取当前数字对应的所有字母,并且把其中的一个字母插入到当前字符串后面,然后继续处理号码的后一位,以此类推,直到遍历完所有的电话号码,得到一个完整的字符串之后,再回退到上一个分支状态,得到另一个字符串
代码(回溯)
var letterCombinations = function(digits) {
if(!digits) return []
const alpha = {
2: "abc",
3: "def",
4: "ghi",
5: "jkl",
6: "mno",
7: "pqrs",
8: "tuv",
9: "wxyz"
}
const dfs =(i,digits,temp)=>{
if(i === digits.length){
res.push(temp.join(''))
return
}
let chars = alpha[digits[i]]
for(let ele of chars) {
temp.push(ele)
dfs(i+1, digits, temp)
temp.pop()
}
}
dfs(0,digits,[])
return res
}
BFS
- 本题比较简单的点在于一般的回溯算法中,在得到结果的时候需要对答案进行判断是否是符合要求的结果,如果不符合的需要舍弃,本题中不会出现不符合结果的字符串,所以直接穷举所有的解就可以得到答案
代码(BFS)
const letterCombinations = (digits) => {
if (!digits) return [];
const map = new Map([
['2', ['a', 'b', 'c']],
['3', ['d', 'e', 'f']],
['4', ['g', 'h', 'i']],
['5', ['j', 'k', 'l']],
['6', ['m', 'n', 'o']],
['7', ['p', 'q', 'r', 's']],
['8', ['t', 'u', 'v']],
['9', ['w', 'x', 'y', 'z']],
]);
const ans = map.get(digits[0]).slice();
for (let i = 1; i < digits.length; ++i) {
for (let j = ans.length - 1; j > -1; --j) {
const str = ans.shift();
map.get(digits[i]).map(char => ans.push(str + char));
}
}
return ans;
};
总结
- 本题难度等级为中等,因为得到的字符串没有非法值,所以不是很典型的回溯,但是因为对回溯算法趁热打铁,还是写了这道题
- 写这道题的时候在想这个可能就是九宫格输入法背后的部分算法,根据按的数字推算出可能得字符串组合,然后对字符串进行拼音的识别,早期的时候,可能是一比一的识别,之后在识别这些字符组合成的字符串的时候,就更加智能,从而提升了打字速度
- 今天也是有收获的一天