当前位置: 首页 > news >正文

【每日算法】LeetCode 17. 电话号码的字母组合

对前端开发者而言,学习算法绝非为了“炫技”。它是你从"页面构建者"迈向"复杂系统设计者"的关键阶梯。它将你的编码能力从"实现功能"提升到"设计优雅、高效解决方案"的层面。从现在开始,每天投入一小段时间,结合前端场景去理解和练习,你将会感受到自身技术视野和问题解决能力的质的飞跃。------ 算法:资深前端开发者的进阶引擎

LeetCode 17. 电话号码的字母组合

1. 题目描述

给定一个仅包含数字2-9的字符串,返回所有它能表示的字母组合。答案可以按任意顺序返回。

数字到字母的映射如下(与电话按键相同):

2: "abc" 3: "def" 4: "ghi" 5: "jkl" 6: "mno" 7: "pqrs" 8: "tuv" 9: "wxyz"

注意:10不包含任何字母。

示例 1:

输入:digits = "23" 输出:["ad","ae","af","bd","be","bf","cd","ce","cf"]

示例 2:

输入:digits = "" 输出:[]

示例 3:

输入:digits = "2" 输出:["a","b","c"]

2. 问题分析

2.1 问题本质

这是一个典型的组合问题,需要找出所有可能的字母排列组合。每个数字对应3-4个字母,我们需要从每个数字对应的字母集合中选取一个字母,然后将所有选出的字母按顺序组合起来。

2.2 关键特征

  1. 组合而非排列:顺序是固定的(按输入数字顺序),我们只需要在每个位置选择合适的字母
  2. 多重循环的变体:相当于多个for循环的嵌套,但循环层数由输入字符串长度决定
  3. 树形结构:可以看作一个树形遍历问题,每个节点代表一个数字,分支代表该数字对应的字母

2.3 前端视角

在前端开发中,类似的问题场景包括:

  • 动态表单生成(根据用户选择动态生成下一级选项)
  • 路由权限组合(不同权限组合对应不同的可访问路由)
  • 商品属性组合(如颜色、尺寸的不同组合)

3. 解题思路

3.1 核心思想:回溯算法

回溯算法是解决组合问题的经典方法,特别适合解决"所有可能"的问题。它通过探索所有可能的路径,并在遇到不可能的情况时回退到上一步。

3.2 算法步骤

  1. 建立数字到字母的映射表
  2. 如果输入字符串为空,直接返回空数组
  3. 初始化结果数组和当前路径
  4. 使用深度优先搜索(DFS)回溯:
    • 终止条件:当前路径长度等于输入数字字符串长度
    • 递归过程:获取当前数字对应的字母,遍历每个字母,将其加入路径,递归处理下一个数字,然后回溯(移除路径最后一个字母)

3.3 复杂度分析

  • 时间复杂度:O(3^m × 4^n),其中 m 是输入中对应3个字母的数字个数,n 是输入中对应4个字母的数字个数
  • 空间复杂度:O(m+n),递归调用栈的深度最大为输入数字的长度

3.4 最优解

回溯算法是这个问题的最优解,因为:

  1. 必须遍历所有可能的组合才能得到完整答案
  2. 避免了不必要的重复计算
  3. 空间复杂度相对较低,只存储当前路径和结果

4. 各思路代码实现

4.1 回溯算法(递归实现)

/** * 方法一:经典回溯算法(递归) * @param {string} digits * @return {string[]} */constletterCombinations=function(digits){if(!digits||digits.length===0)return[];// 数字到字母的映射constdigitMap={'2':'abc','3':'def','4':'ghi','5':'jkl','6':'mno','7':'pqrs','8':'tuv','9':'wxyz'};constresult=[];/** * 回溯函数 * @param {number} index - 当前处理的数字索引 * @param {string} current - 当前组合字符串 */constbacktrack=(index,current)=>{// 终止条件:当前组合长度等于输入数字长度if(index===digits.length){result.push(current);return;}// 获取当前数字对应的字母constdigit=digits[index];constletters=digitMap[digit];// 遍历当前数字对应的所有字母for(leti=0;i<letters.length;i++){// 做出选择:添加当前字母到组合中backtrack(index+1,current+letters[i]);// 回溯:在递归返回后,current不变,无需显式移除字符}};backtrack(0,'');returnresult;};

4.2 迭代法(队列实现)

/** * 方法二:迭代法(使用队列) * @param {string} digits * @return {string[]} */constletterCombinationsQueue=function(digits){if(!digits||digits.length===0)return[];constdigitMap={'2':'abc','3':'def','4':'ghi','5':'jkl','6':'mno','7':'pqrs','8':'tuv','9':'wxyz'};// 使用队列存储中间结果letqueue=[''];for(leti=0;i<digits.length;i++){constdigit=digits[i];constletters=digitMap[digit];constqueueLength=queue.length;// 处理队列中现有的所有组合for(letj=0;j<queueLength;j++){constcurrent=queue.shift();// 取出队首元素// 为当前组合添加新的字母for(letk=0;k<letters.length;k++){queue.push(current+letters[k]);}}}returnqueue;};

4.3 函数式编程实现

/** * 方法三:函数式编程实现 * @param {string} digits * @return {string[]} */constletterCombinationsFP=function(digits){if(!digits||digits.length===0)return[];constdigitMap={'2':'abc','3':'def','4':'ghi','5':'jkl','6':'mno','7':'pqrs','8':'tuv','9':'wxyz'};// 使用reduce逐步构建所有组合returndigits.split('').reduce((acc,digit)=>{constletters=digitMap[digit];if(acc.length===0){returnletters.split('');}// 将现有组合与新的字母进行笛卡尔积returnacc.flatMap(comb=>letters.split('').map(letter=>comb+letter));},[]);};

5. 各实现思路的复杂度、优缺点对比

实现方法时间复杂度空间复杂度优点缺点适用场景
回溯算法(递归)O(3^m × 4^n)O(m+n)1. 思路清晰直观
2. 代码简洁
3. 标准解法,易于理解
1. 递归深度受栈大小限制
2. 字符串拼接产生新字符串
大多数场景,教学示例,中等长度输入
迭代法(队列)O(3^m × 4^n)O(3^m × 4^n)1. 避免递归栈溢出
2. 适合大长度输入
3. 容易理解
1. 空间占用较大
2. 代码稍复杂
输入较长,担心递归深度限制
函数式编程O(3^m × 4^n)O(3^m × 4^n)1. 代码简洁优雅
2. 无副作用
3. 易于测试
1. 性能稍差
2. 可能产生中间数组
3. 理解需要函数式基础
函数式代码库,小规模输入,代码简洁性优先

6. 总结

6.1 算法核心要点

  1. 回溯算法是解决组合问题的利器,特别适合需要探索所有可能解的场景
  2. 递归与迭代可以相互转换,根据具体情况选择合适的方法
  3. 剪枝优化:虽然本题无法剪枝(需要所有组合),但在其他问题中可以通过条件判断提前终止无效分支

6.2 前端实际应用场景

场景一:动态表单生成器
// 根据用户选择的选项动态生成下一级选项// 例如:选择省份 -> 选择城市 -> 选择区域functiongenerateFormCombinations(selections){// 类似电话号码组合,每个选择点对应多个选项// 生成所有可能的表单路径}
场景二:路由权限组合
// 用户可能有多种角色,每种角色对应不同的权限// 计算用户可以访问的所有路由组合functiongetAllowedRoutes(userRoles){// 每个角色对应一组可访问路由// 组合所有角色的路由权限}
场景三:商品SKU组合
// 电商平台中,商品可能有多个属性(颜色、尺寸等)// 生成所有可能的SKU组合functiongenerateProductSKUs(attributes){// 例如:颜色:红、蓝;尺寸:S、M、L// 生成:红-S、红-M、红-L、蓝-S、蓝-M、蓝-L}
场景四:国际化文案组合
// 多语言网站中,根据语言和地区组合生成完整的文案路径functiongetI18nPaths(languages,regions){// 例如:语言:en, zh;地区:US, CN// 生成:en-US, en-CN, zh-US, zh-CN}
http://www.cnnetsun.cn/news/131324.html

相关文章:

  • Twitch掉落自动获取工具:告别手动挂机的智能解决方案
  • 百考通AI:您的智能开题导师,一键生成完美开题报告,让科研之路赢在起点!
  • 如何快速搭建StaMPS:InSAR数据处理完整实战指南
  • 百度网盘下载限速如何彻底解决?Mac用户专属的3步加速方案
  • 传感器数据融合失败?根源竟在初始外参校准(内附工业级校准流程图)
  • 物流仓储分拣效率瓶颈全解析(Agent智能优化大揭秘)
  • WorkTool企业微信自动化工具:从零开始的完整实战指南
  • 你还在用遗传算法?量子Agent已实现全局最优路径动态生成!
  • MCP DP-420图Agent性能调优实战:9个关键指标详解与3倍响应加速秘技
  • 【紧急避坑指南】:云边协同部署中Agent任务分配的4大致命错误
  • 【教育测评Agent自动批改揭秘】:如何用AI实现99%准确率的智能评分系统
  • 英雄联盟智能助手ChampR:5分钟快速上手的终极游戏配置方案
  • 设备数据采集效率提升300%?看这家头部企业Agent部署实战
  • 【dz-996】物联网的家居环境预警监测系统
  • 【dz-998】导盲犬多功能喂食器的设计与实现
  • 终极Windows动态桌面指南:打造个性化视频壁纸的完整教程
  • Mem Reduct系统优化评测:告别卡顿的智能性能管家
  • Luckysheet单元格数据验证功能深度解析:从入门到实战完整指南
  • 工业互联网Agent设备认证安全方案(三大高危漏洞防御策略)
  • APK Installer完整指南:快速在Windows上安装Android应用
  • MCP续证常见失败原因曝光:这6个预约陷阱千万别踩(附解决方案)
  • Azure量子计算错误处理全攻略(企业级容错方案首次公开)
  • Cursor试用限制完全重置指南:告别“Too many trial accounts“错误
  • 终极指南:如何在Android设备实现离线语音转文字?
  • Termius中文版终极教程:安卓设备轻松管理远程服务器
  • 如何让交易Agent跑得比市场还快?:基于FPGA与内存池的极速实现
  • 机器学习第二部分----逻辑回归
  • 【Offline RL 核心】第 2 篇|分布外动作与 Q 值高估:当 AI 开始“白日做梦”
  • Frigate智能监控终极指南:3步搞定go2rtc流媒体配置
  • 如何解决AMD显卡驱动臃肿问题