「算法」LeetCode 17. 电话号码的字母组合(JavaScript版)

本文介绍了如何使用JavaScript解决LeetCode第17题——电话号码的字母组合。通过建立数字与字母的映射,利用递归实现字母的两两组合。文中提供了解法1的详细步骤,并提及了DFS解法待补充。同时,讨论了块级作用域在解题过程中的应用,特别是在处理边界条件和数组操作时应注意的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

老规矩,题目链接:https://leetcode-cn.com/problems/letter-combinations-of-a-phone-number/
这道题的解法至少有两种,但由于本人才疏学浅,只弄懂了一种(留坑,学成后填上),如果别的小伙伴还有更好的解决办法或是觉得我的方法不正确,欢迎大家在评论区提出来~

解法1:

export default (str) => {
    // 建立电话号码键盘映射
    let map = ['', 1, 'abc', 'def', 'ghi', 'jkl', 'mno', 'pqrs', 'tuv', 'wxyz'];
    // 将输入的字符串分割成单个字符,如 123 => [2, 3, 4]
    let num = str.split('');
    // 保存键盘映射后的内容,如 23 => ['abc', 'def']
    let code = [];
    // 遍历数组num,不为空则保存到code中
    num.forEach((item) => {
        if (map[item]) {
            code.push(map[item]);
        }
    });
    // 判断边界条件
    if (!str) {
    	// 为空返回空数组
        return [];
    } else if (str.length === 1) {
    	// 只有一项时返回该项拆分后得到的数组
        return code[0].split('');
    } else {
    	// 注意使用var而不是let,避开块级作用域问题
        var comb = (arr) => {
            // 用于保存前两个组合结果的临时变量
            let tmp = [];
            for (let i = 0; i < arr[0].length; i++) {
                for (let j = 0; j < arr[1].length; j++) {
                	// 将组合后的字符串保存到tmp中
                    tmp.push(`${arr[0][i]}${arr[1][j]}`);
                }
            }
            // 前两项已经被合并成了tmp中的元素,删除前两项并替换成tmp中的元素
            arr.splice(0, 2, tmp);
            if (arr.length > 1) {
                comb(arr);
            } else {
                return tmp;
            }
            return arr[0];
        };
    }
    // 最后调用comb方法,若声明comb方法时使用了let,此处报错
    return comb(code);
}

解法1的思路如下:
首先建立电话号码键盘的映射数组map,将输入的按键数字字符串分割成单个数字保存到数组num中,对数组num进行遍历,得到对应的映射关系并保存到数组code中。接下来就采用递归的方式对数组code进行处理,将数组code中的每一个元素的每一个字母使用for循环两两组合,组合完成后保存在临时数组tmp中,由于从头开始组合,因此两两组合完成后采用splice方法,将前两项删除,替换为组合完成后得到的临时数组tmp,当数组code中的元素只剩下一个的时候,停止递归,返回临时数组tmp,然后返回数组code的第一项,即为临时数组tmp,最后调用comb方法,即为题解。

解法2:
DFS(待更填坑)

其他解法:
等等……

小结:
这道题要求理清数字与字母的映射关系,建立好映射关系后,题目就解出了一大半。采用了分治法的思想,当传入的数字只有两个时,能够很容易解决,以此类推,采用两两组合的方式可以很轻易地解出当传入的数字为三个、四个、五个、n个时的结果。这个题目涉及到了一个ES6中块级作用域的知识点。

解题笔记:

  1. 理清题意,建立数字与字母的映射关系
  2. forEach方法可以办理数组中的每一项
  3. splice方法可以将数组中的元素删除或新增,第一个参数为删除的起始点,第二个参数为需要删除的元素个数,第三个参数可选,为需要新增的数组元素
  4. 注意边界条件,即当输入为空或输入仅有一项时的边界条件
  5. 注意let和var的区别,let存在块级作用域的问题,在此题中的comb函数定义时使用let会导致最后return时comb出现undefined的情况
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值