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

LeetCode算法题:电话号码的字母组合

题目描述:

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

给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。

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

例如,给定 digits = "23",返回 ["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"]

注意:2 对应的字母是 "abc"3 对应的字母是 "def",以此类推。每个数字可以对应 3 到 4 个字母。


解题思路:

本题通过回溯算法(Backtracking)来求解。回溯算法是一种通过递归的方法尝试所有可能的解,并在发现无解时回退的算法。回溯的思想很适合这种生成所有可能组合的题目。

步骤概述

  1. 数字映射字母:我们首先创建一个映射关系,数字和字母的对应关系被存储在一个 Map 中。例如,数字 2 映射到字母字符串 "abc",数字 3 映射到字母字符串 "def",等等。

  2. 回溯算法:从字符串的第一个数字开始,递归地遍历每个数字对应的所有字母,将每个字母依次添加到当前组合中。当遍历完所有数字后,将组合添加到结果列表中。

  3. 结束条件:当遍历到数字字符串的末尾时,表示已经生成了一个有效的字母组合,将其加入结果列表。


回溯算法的详细步骤:

  1. 初始化

    • 创建一个 Map 存储数字到字母的映射。

    • 创建一个空的 List<String> 来存储最终的字母组合结果。

  2. 回溯函数

    • 使用递归的方式遍历每个数字对应的所有字母,逐个将字母加入当前组合(使用 StringBuffer 以提高效率)。

    • 当递归到达数字字符串的末尾时,表示已经生成了一个有效的字母组合,将其添加到结果列表中。

    • 在递归返回时,撤销上一步的操作(即删除最后加入的字母),尝试其他字母。

  3. 终止条件

    • 当递归到达数字字符串的末尾时,表示已经生成了一种组合,返回并保存结果。


代码实现:

class Solution {public List<String> letterCombinations(String digits) {List<String> combinations = new ArrayList<>();if(digits.length() == 0){return combinations; // 如果输入为空,直接返回空结果}// 创建数字到字母的映射关系Map<Character,String> map = new HashMap<>();map.put('2',"abc");map.put('3',"def");map.put('4',"ghi");map.put('5',"jkl");map.put('6',"mno");map.put('7',"pqrs");map.put('8',"tuv");map.put('9',"wxyz");// 调用回溯算法backtracking(combinations, digits, 0, map, new StringBuffer());return combinations;}// 回溯算法public void backtracking(List<String> combinations, String digits, int index, Map<Character, String> map, StringBuffer combination) {// 回溯结束条件:当index等于字符串长度时,表示我们已经完成了一个字母组合if(index == digits.length()) {combinations.add(combination.toString()); // 将组合添加到结果集} else {// 获取当前数字对应的字母char digit = digits.charAt(index);String letters = map.get(digit);for(int i = 0; i < letters.length(); i++) {combination.append(letters.charAt(i)); // 将字母加入组合backtracking(combinations, digits, index + 1, map, combination); // 递归调用处理下一个数字combination.deleteCharAt(combination.length() - 1); // 撤销操作,回到上一步}}}
}

代码解析:

  1. 主函数 letterCombinations

    • 检查 digits 是否为空。如果为空,直接返回空列表。

    • 初始化数字到字母的映射 map

    • 调用回溯函数 backtracking,开始递归生成字母组合。

  2. 回溯函数 backtracking

    • index 表示当前处理到数字字符串的哪个位置。

    • index 等于 digits.length() 时,表示已经生成一个完整的字母组合,将其添加到结果集 combinations 中。

    • 否则,遍历当前数字对应的所有字母,将字母依次加入当前的组合(combination),然后递归地处理下一个数字。

    • 回溯时,撤销上一步的字母,恢复组合状态,继续尝试其他字母。

  3. 递归与回溯

    • 递归的核心思想是逐步选择每个数字对应的字母,直到遍历完所有数字。

    • 回溯的关键是撤销上一步的选择(通过 combination.deleteCharAt()),以便尝试其他可能的字母。


时间复杂度分析:

假设输入的数字串长度为 n,每个数字最多对应 4 个字母(如数字 79),最少对应 3 个字母(如数字 26)。

  • 每次递归调用中,我们要遍历当前数字对应的所有字母,因此每次递归的时间复杂度为 O(3)O(4)

  • 总的递归深度是 n(因为我们递归到数字串的末尾),因此总的时间复杂度是 O(4^n),即每个数字有 4 种可能字母,递归深度为 n

空间复杂度:

  • 回溯过程中会维护一个字符串 combination,其大小最大为 n。因此空间复杂度为 O(n)

  • 结果集 combinations 存储了所有字母组合,大小为 4^n,因此空间复杂度为 O(4^n)


总结:

  • 本题通过回溯算法(Backtracking)高效地生成所有可能的字母组合。

  • 回溯算法利用递归的思想,在逐步构建字母组合的过程中,保持对状态的控制,直到所有可能的组合都生成完毕。

  • 该算法的时间复杂度较高,但适用于这类需要生成所有组合或排列的问题。

相关文章:

  • T2000云腾边缘计算盒子在数猪场景中的应用|YOLOv8+NodeRED
  • 软考 系统架构设计师系列知识点之杂项集萃(57)
  • VS2019 - 修正导出项目的工程模板的错误
  • UI自动化测试框架:PO 模式+数据驱动
  • 长度最小的子数组(leetcode)
  • 联想混合式AI的“动力总成”构建记
  • 【Redis 进阶】哨兵模式
  • KUKA机器人中断编程2—中断相关的指令
  • JDK 安装与配置
  • cursor Too many报错 显示锁机器码怎么办?也就是Cursor的
  • 配置集群(yarn)
  • 医药级食品树脂杜笙树脂医药溶液去除苦味溶液净化
  • 未来技术展望:光子量子计算集成与连续变量可视化
  • CATIA高效工作指南——常规配置篇(二)
  • Kotlin与Qt跨平台框架深度解析:业务逻辑共享与多语言集成
  • 51 单片机头文件 reg51.h 和 reg52.h 详解
  • C++编程练习,认识面向对象权限,如何进行封装
  • 深度解析mybatisplus中出现的循环依赖问题
  • (自用)Java学习-5.9(Thymeleaf,自动装配,自定义启动器 )
  • 旋转图像算法讲解
  • 沙县小吃中东首店在沙特首都利雅得开业,首天营业额5万元
  • 夜读丨取稿费的乐趣
  • 教育部基础教育教指委:稳步推进中小学人工智能通识教育
  • 石家庄推动城市能级与民生福祉并进
  • 韩国执政党总统候选人更换方案被否决,金文洙候选人资格即刻恢复
  • 巴基斯坦首都及邻近城市听到巨大爆炸声