LeetCode 17. 电话号码的字母组合:回溯算法入门实战
LeetCode中等难度题目——17. 电话号码的字母组合这道题是回溯算法的经典入门题既能帮我们熟悉回溯的核心思想又能巩固字符串、哈希表的基础用法非常适合新手上手练习。一、题目解析读懂需求明确边界先看题目要求给定一个仅包含数字 2-9 的字符串返回所有它能表示的字母组合答案可以按任意顺序返回。核心映射关系和手机按键一致2 → abc3 → def4 → ghi5 → jkl6 → mno7 → pqrs8 → tuv9 → wxyz关键边界条件输入为空字符串digits.length 0时直接返回空数组数字仅包含2-9无需处理11不对应任何字母输出需包含所有可能的组合无重复、无遗漏。举个例子输入 “23”输出应该是 [“ad”,“ae”,“af”,“bd”,“be”,“bf”,“cd”,“ce”,“cf”]因为2对应abc3对应def每个字母两两组合就是所有可能的结果。二、解题思路为什么选回溯算法这道题的核心是「穷举所有可能的组合」而回溯算法正是解决「穷举组合」类问题的最优思路之一。什么是回溯简单来说就是「走一步、试一步走不通就退回来换条路走」本质是一种深度优先搜索DFS只不过在搜索过程中会「回溯」到上一步继续尝试其他可能性。对应这道题我们可以这样理解先取第一个数字对应的所有字母逐个选择一个字母作为组合的第一个字符再取第二个数字对应的所有字母逐个拼接在第一个字符后面作为组合的第二个字符以此类推直到拼接的字符长度等于输入数字的长度说明已经处理完所有数字就把这个组合加入结果集当一个数字的所有字母都尝试完就回溯到上一个数字换一个字母继续拼接直到所有可能性都被尝试完。举个通俗的例子输入 “23”流程就是a→d加入结果→a→e加入结果→a→f加入结果→回溯到aa的所有字母尝试完回溯到2换b→b→d加入结果→b→e加入结果…… 以此类推直到所有组合都被生成。三、完整代码实现TypeScript下面是完整的解题代码注释已经写得非常详细大家可以先通读一遍后续逐句拆解functionletterCombinations(digits:string):string[]{// 边界条件输入为空直接返回空数组if(digits.length0)return[];// 建立数字到字母的映射表用Map存储查询更高效constmapnewMap([[2,abc],[3,def],[4,ghi],[5,jkl],[6,mno],[7,pqrs],[8,tuv],[9,wxyz]]);// 存储最终结果的数组constresult:string[][];// 输入数字串的长度用于判断终止条件constdigitsLen:numberdigits.length;/** * 回溯函数递归生成字母组合 * param {number} index - 当前处理的数字在digits中的索引 * param {string} currentStr - 当前已经拼接好的字母组合 * returns */constbacktrack(index:number,currentStr:string){// 终止条件当处理完所有数字索引等于数字串长度将当前组合加入结果集if(indexdigitsLen){result.push(currentStr);return;}// 取出当前数字对应的字母加非空判断增强代码健壮性避免异常constlettersmap.get(digits[index]);if(!letters)return;// 遍历当前数字对应的每一个字母递归拼接letters.split().forEach((letter:string){// 字符串不可变currentStr letter 会生成新字符串无需手动回溯天然回溯backtrack(index1,currentStrletter);});}// 启动回溯从第0个数字开始初始拼接字符串为空backtrack(0,);// 返回最终结果returnresult;};四、代码逐句拆解读懂每一步的意义1. 边界条件处理if (digits.length 0) return [];这一步很关键当输入为空字符串时没有任何组合可以生成直接返回空数组避免后续递归报错。2. 建立数字-字母映射用Map存储映射关系相比对象ObjectMap的get方法查询效率更高而且可以直接用数组初始化代码更简洁。这里明确了每个数字对应的字母和题目要求完全一致。3. 初始化变量result: string[] []用于存储所有生成的字母组合最终作为返回值digitsLen: number digits.length存储输入数字串的长度避免在递归中多次调用digits.length提升性能虽然影响不大但养成良好习惯。4. 核心回溯函数backtrack回溯函数是这道题的灵魂我们重点拆解它的两个参数和内部逻辑参数说明index: number当前正在处理的数字在digits中的索引比如输入23index0时处理数字2index1时处理数字3currentStr: string当前已经拼接好的字母组合比如index0时currentStr可能是a、“b”、“c”index1时currentStr可能是ad、ae等。终止条件if (index digitsLen) { result.push(currentStr); return; }当index等于数字串的长度时说明我们已经处理完了所有数字当前的currentStr就是一个完整的组合把它加入result然后返回结束当前递归回溯到上一步。获取当前数字对应的字母const letters map.get(digits[index]); if (!letters) return;根据当前index取出digits中对应的数字再通过Map获取该数字对应的字母串。加一个非空判断防止出现异常虽然题目说输入仅包含2-9但健壮性代码不能少。遍历字母递归拼接letters.split().forEach((letter: string) { backtrack(index 1, currentStr letter); });这一步是回溯的核心逻辑将字母串拆分成单个字母比如abc拆成[“a”,“b”,“c”]遍历每个字母调用回溯函数此时index1处理下一个数字currentStrletter将当前字母拼接到已有的组合上这里有个小技巧因为字符串是不可变的currentStr letter会生成一个新的字符串而不是修改原字符串所以当递归结束后会自动回到上一步的currentStr无需手动“回溯”比如拼接完ad递归结束后会回到a继续拼接ae。5. 启动回溯backtrack(0, );从第一个数字index0开始初始的拼接字符串为空启动递归流程开始生成所有组合。五、易错点提醒 优化方向易错点忘记处理输入为空的情况导致递归报错回溯函数的终止条件写错比如写成index digitsLen导致组合缺失或重复没有加非空判断if (!letters) return虽然题目输入合法但代码不够健壮混淆index的含义导致处理数字时出现偏差。优化方向这道题的解法已经很高效了但可以做一些小优化提升可读性和性能用数组代替Map存储映射关系比如const map [, , abc, def, ...]通过索引直接获取数字字符转数字即可比如digits[index] - 0查询速度更快用数组拼接代替字符串拼接因为字符串不可变频繁拼接会生成新字符串数组pushjoin效率更高比如用currentArr存储当前组合递归时push(letter)回溯时pop()最后join成字符串加入结果集。优化后的回溯函数数组拼接版constbacktrack(index:number,currentArr:string[]){if(indexdigitsLen){result.push(currentArr.join());return;}constlettersmap.get(digits[index]);if(!letters)return;letters.split().forEach(letter{currentArr.push(letter);// 加入当前字母backtrack(index1,currentArr);currentArr.pop();// 回溯移除最后一个字母});}// 启动回溯backtrack(0,[]);六、总结回溯算法的核心要点通过这道题我们可以总结出回溯算法解决组合问题的通用步骤确定「终止条件」当满足某个条件比如处理完所有元素将当前结果加入结果集返回确定「递归逻辑」遍历当前可选的所有元素逐个选择递归处理下一个元素「回溯操作」要么利用不可变类型如字符串天然回溯要么手动回溯如数组pop()回到上一步继续尝试。这道题作为回溯入门题难度适中理解透彻后再去做LeetCode上其他回溯题目比如组合总和、子集会轻松很多。

相关新闻

弦音墨影部署案例:高校AI实验室用消费级显卡部署水墨视频理解教学平台

弦音墨影部署案例:高校AI实验室用消费级显卡部署水墨视频理解教学平台

弦音墨影部署案例:高校AI实验室用消费级显卡部署水墨视频理解教学平台 1. 项目背景与需求 某高校人工智能实验室面临一个实际教学难题:视频理解与多模态分析是AI教学的重要环节,但传统解决方案要么需要昂贵的专业显卡,要么界面复…

2026/5/17 9:51:26 阅读更多 →
实战应用:借鉴zlibrary思路,用快马打造团队内部资料库

实战应用:借鉴zlibrary思路,用快马打造团队内部资料库

最近在团队协作中,我们遇到了一个很实际的问题:项目资料、技术文档、会议纪要散落在各个成员的电脑、聊天记录和网盘里,查找起来特别费劲。大家需要一个集中的地方来存放和查找这些资料,就像我们平时找电子书会去zlibrary一样方便…

2026/7/3 22:24:04 阅读更多 →
视频压缩革新:CompressO如何重塑你的数字存储体验

视频压缩革新:CompressO如何重塑你的数字存储体验

视频压缩革新:CompressO如何重塑你的数字存储体验 【免费下载链接】compressO Convert any video into a tiny size. 项目地址: https://gitcode.com/gh_mirrors/co/compressO 你是否曾遇到这样的困境:手机相册被几个GB的视频占满,想分…

2026/5/17 9:51:22 阅读更多 →

最新新闻

Codex 完整使用教程(Windows/macOS 双系统区别详解)

Codex 完整使用教程(Windows/macOS 双系统区别详解)

一、Codex 基础介绍OpenAI Codex 是专为代码生成、调试、重构、自动化系统操作打造的AI模型,也是OpenAI面向开发者的核心编程智能体,支持自然语言转代码、批量代码处理、本地文件操作、终端指令自动化等功能,适配 Windows、macOS 双平台&…

2026/7/5 1:42:22 阅读更多 →
郴州热门火锅店理性测评|行业避坑+科学选型指南

郴州热门火锅店理性测评|行业避坑+科学选型指南

一、引言:郴州火锅消费乱象与选型痛点依托文旅消费回暖、夜间经济扩容红利,郴州餐饮市场热度持续走高,火锅作为本地聚餐首选品类,门店数量逐年递增。结合2026年湘南餐饮消费数据,郴州火锅门店超320家,其中川…

2026/7/5 1:42:22 阅读更多 →
Minecraft服务器包创建终极指南:5分钟自动化部署解决方案

Minecraft服务器包创建终极指南:5分钟自动化部署解决方案

Minecraft服务器包创建终极指南:5分钟自动化部署解决方案 【免费下载链接】ServerPackCreator Create a server pack from a Minecraft Forge, NeoForge, Fabric, LegacyFabric or Quilt modpack! 项目地址: https://gitcode.com/gh_mirrors/se/ServerPackCreator…

2026/7/5 1:38:20 阅读更多 →
Python异步代理池实战:从requests阻塞到httpx.AsyncClient,爬虫效率翻倍的踩坑记录

Python异步代理池实战:从requests阻塞到httpx.AsyncClient,爬虫效率翻倍的踩坑记录

一、起因:代理验证拖垮了整个采集系统先交代一下背景。我在一家电商公司做数据采集,核心系统是竞品价格监控——每天爬天猫、京东、拼多多的商品价格,日采集量在几十万到百万级。刚开始做的时候,代理管理这块是比较粗糙的——抓了…

2026/7/5 1:36:20 阅读更多 →
因为刷短视频导致流量费用每个月暴涨5块钱

因为刷短视频导致流量费用每个月暴涨5块钱

上个月有一天流量使用了10G,这几乎不太可能,但是也不是完全不可能。如果120K/s 9个小时不停下载--------------目前就是这个状态。然后就会有4G/天 流量花费一个月下来就是120G,本身流量只有20G,虽然剩下流量不限量,但…

2026/7/5 1:34:19 阅读更多 →
【无人机】基于玻尔兹曼引导的 Q 学习用于在受洪水影响的无线网络中优化 3D 无人机部署附matlab代码

【无人机】基于玻尔兹曼引导的 Q 学习用于在受洪水影响的无线网络中优化 3D 无人机部署附matlab代码

✅作者简介:热爱科研的Matlab仿真开发者,擅长毕业设计辅导、数学建模、数据处理、算法改进、程序设计科研仿真。🍎完整代码获取 定制创新 论文复现私信🍊个人信条:做科研,博学之、审问之、慎思之、明辨之、…

2026/7/5 1:34:19 阅读更多 →

日新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/5 0:03:34 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/5 0:03:34 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/5 0:07:38 阅读更多 →

周新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/5 0:03:34 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/5 0:03:34 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/5 0:07:38 阅读更多 →

月新闻