刷题笔记:力扣第17题-电话号码的字母组合

1.题目不难理解,本质上就是一类找全部组合的问题,需要用到递归算法,2-9每个数字都代表一层递归。可以定义一个字符串数组vis来记录2-9的字母映射,同时定义一个数组visLen记录2-9映射的字母数量:

cpp 复制代码
1. const char *vis[8] = {"abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
2. const int visLen[8] = {3, 3, 3, 3, 3, 4, 3, 4};

递归里面的终止条件为当前指针等于传入的数字字符串长度,复制path的字符串到tmp并记录到结果数组,之后返回。每层递归的核心逻辑为遍历当前数字对应的全部字母,记录每一个本层字母的时候都可以进入下一层递归,本层字母全都取过后自动返回上一层。

2.基于以上思想,可写出完整代码如下:

cpp 复制代码
 1. /**
 2.  * Note: The returned array must be malloced, assume caller calls free().
 3.  */
 4.  
 5. // 数字2~9 对应字母的映射表(指针数组,最标准写法)
 6. // 索引 0 → 数字2,索引1→数字3 ... 索引7→数字9
 7. const char *vis[8] = {"abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
 8.  
 9. // 每个数字对应多少个字母(3个或4个)
10. const int visLen[8] = {3, 3, 3, 3, 3, 4, 3, 4};
11.  
12. char* path;        // 回溯时:保存当前正在拼接的字母组合
13. int pathSize;      // 当前组合的长度
14. char** res;        // 最终结果:保存所有字母组合
15. int resSize;       // 最终结果有多少个组合
16.  
17. void dfs(int startStr, char* digits, int len){
18.     // ===================== 递归终止条件 =====================
19.     // 已经处理完所有数字 → 当前path是一个完整组合
20.     if (startStr == len){
21.         // 给这个组合分配内存(+1 存字符串结束符 \0)
22.         char* tmp = (char*)malloc(sizeof(char) * (pathSize + 1));
23.         // 把当前path复制到新内存
24.         memcpy(tmp, path, sizeof(char) * pathSize);
25.         // C语言字符串必须加结束符
26.         tmp[pathSize] = '\0';
27.         // 放入结果集
28.         res[resSize++] = tmp;
29.         return;
30.     }
31.  
32.     // ===================== 核心回溯循环 =====================
33.     // 遍历当前数字对应的所有字母
34.     for (int cur = 0; cur < visLen[digits[startStr] - '2']; cur++){
35.         // 选一个字母,加入当前组合
36.         path[pathSize++] = vis[digits[startStr] - '2'][cur];
37.         // 递归处理下一个数字
38.         dfs(startStr + 1, digits, len);
39.         // 回溯:撤销选择,删掉最后一个字母
40.         pathSize--;
41.     }
42. }
43.  
44. char** letterCombinations(char* digits, int* returnSize) {
45.     // 初始化全局变量
46.     pathSize = resSize = 0;
47.     int len = strlen(digits);
48.  
49.     // 分配结果数组空间:最多 4^4 = 256 种组合
50.     res = (char**)malloc(sizeof(char*) * 256);
51.     // 分配临时组合空间:最长 len 个字母
52.     path = (char*)malloc(sizeof(char) * (len + 1));
53.  
54.     // 开始回溯
55.     dfs(0, digits, len);
56.  
57.     // 返回结果数量
58.     *returnSize = resSize;
59.     // 返回所有组合
60.     return res;
61. }

该算法的时间复杂度为O(3^m×4^n),其中m是对应3个字母的数字个数(2,3,4,5,6,8),n是对应4个字母的数字个数(7,9),空间复杂度为O(len),已是本题最优解。

相关推荐
kkeeper~4 小时前
0基础C语言积跬步之数据在内存中的存储
c语言·数据结构·算法
鹏北海-RemHusband5 小时前
Go 语言进阶笔记 — 面向 JS/TS 前端开发者
笔记·golang
wabs6665 小时前
关于贪心算法的一些自我总结【力扣45.跳跃游戏II】【灵感来源:代码随想录】
算法·贪心算法·复盘
2401_876964135 小时前
【湖北专升本】2026湖北专升本真题PDF+备考资料汇总
数据结构·人工智能·经验分享·深度学习·算法·计算机视觉
嗝o゚6 小时前
CANN GE 算子融合——融合算法与调度策略
算法·昇腾·cann·ge
小江的记录本6 小时前
【JVM虚拟机】垃圾回收GC:垃圾回收算法:标记-清除、标记-复制、标记-整理、分代收集(附《思维导图》+《面试高频考点清单》)
java·jvm·后端·python·算法·安全·面试
nnsix7 小时前
Unity QFramework ResKit、UIKit 笔记
笔记
摇滚侠8 小时前
Java 零基础全套教程,反射机制,笔记 187-188
java·开发语言·笔记
Ulyanov8 小时前
用声明式语法重新定义Python桌面UI:QML+PySide6现代开发入门(一)
开发语言·python·算法·ui·系统仿真·雷达电子对抗仿真
数据科学小丫8 小时前
特征工程处理
人工智能·算法·机器学习