小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
说明:文章部分内容及图片出自网络,如有侵权请与我本人联系(主页有公众号:小攻城狮学前端)
作者:小只前端攻城狮、 主页:小只前端攻城狮的主页、 来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
题目描述
给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
解题思路
题目的最终要求就是让对提供的字符串(S)中包含的数字以 数字出现的顺序为顺序 进行全排列。因为每个数字有其映射关系,所以建立字典表进行快速查询。
1、DFS 状态树
只要不满足终止条件(要么遇到 0、1,要么当前组合的长度 与 S 的长度不一致),就继续去组合生成新的分支
var letterCombinations = function(digits) {
if(digits.length === 0) {
return []
}
const dictionary = {
2: 'abc',
3: 'def',
4: 'ghi',
5: 'jkl',
6: 'mno',
7: 'pqrs',
8: 'tuv',
9: 'wxyz'
}
let result = [];
const dfs = (str, index) => {
// 当 index 等于 原始字符串时,说明当前分支已经组合完毕
// 可以结束递归了
if(index >= digits.length) {
result.push(str)
return
}
// 获取当前数字对应的 字母集合
let map = dictionary[digits[index]];
// 处理 1 、0 等异常边界
if(map) {
// 当前字母集合中的每一个元素和上层递归中生成的更多的字符组合
for(let i of map) {
// 需要加入组合的位置向后移动
dfs(str+i, index+1);
}
}
}
// 从字符串第一个位置开始组合
dfs('', 0);
return result
};
2、BFS 状态树
每次都收集当前层的组合状态,并将这些组合状态 作为下一层的生成 新的组合的基准值
var letterCombinations = function(digits) {
if(digits.length === 0) {
return []
}
const dictionary = {
2: 'abc',
3: 'def',
4: 'ghi',
5: 'jkl',
6: 'mno',
7: 'pqrs',
8: 'tuv',
9: 'wxyz'
}
let result = [];
// bfs
// 1、处理首位的 数值 为 1 或者 0 的情况
// 2、生成初始 的 组合基准值 方便使用while循环(手动初始化迭代栈)
if(digits[0] && digits[0] !== 1) {
result.push(...dictionary[digits[0]]);
}
let index = 1, map, temp;
while (index < digits.length) {
// 获取当前数字对应的 字母集合
map = dictionary[digits[index]];
if(map) {
// 用于记录 当前层的所有组合情况
temp = []
for (let i = 0; i < map.length; i++) {
for(let j = 0; j < result.length; j++) {
// 以 前一个 数字 对应 组合条件为基准 生成的 组合状态
temp.push(result[j] + map[i]);
}
}
// 更新组合的状态
result = temp;
}else {
// 遇到 0、1 循环终止
break;
}
// 更新index,准备取下一个位置的数值
index++;
}
return result
};
感谢阅读,希望能对你有所帮助,文章若有错误或者侵权,可以在评论区留言或在我的主页添加公众号联系我。
写作不易,如果觉得不错,可以「点赞」+「评论」 谢谢支持❤