🌈【LeetCode 电话号码的字母组合】- JavaScript => BFS、DFS

431 阅读3分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。


说明:文章部分内容及图片出自网络,如有侵权请与我本人联系(主页有公众号:小攻城狮学前端)

作者:小只前端攻城狮、 主页:小只前端攻城狮的主页、 来源:掘金

GitHub:P-J27、 CSDN:PJ想做前端攻城狮

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


题目描述

给定一个仅包含数字 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
};

感谢阅读,希望能对你有所帮助,文章若有错误或者侵权,可以在评论区留言或在我的主页添加公众号联系我。

写作不易,如果觉得不错,可以「点赞」+「评论」 谢谢支持❤