刷题笔记:力扣第38题-外观数列

1.拿到本题后看到"迭代"的进阶提示,想到可以使用for循环来进行迭代,只需要将迭代的代码解决即可。迭代逻辑不难理解,遍历当前的字符串,记录当前元素重复的次数与本身的值,传入结果字符串即可。为了每次操作的时候不破坏原有字符串的结构,需要额外创建一个字符串来进行操作,操作完成后拷贝到结果字符串中。

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

cpp 复制代码
 1. char* countAndSay(int n) {
 2.     // 分配结果字符串内存(n≤30 时最长约 4000+,5000 足够)
 3.     char* res = (char*)calloc(5000, sizeof(char));
 4.     // 临时字符串:用于存储每一轮的编码结果
 5.     char* tmp = (char*)calloc(5000, sizeof(char));
 6.     // 初始值:countAndSay(1) = "1"
 7.     res[0] = '1';
 8.  
 9.     // 从第 2 项迭代到第 n 项(共 n-1 轮)
10.     for (int i = 1; i < n; i++){
11.         int len = strlen(res);       // 当前 res 的长度
12.         int cur1 = 0;                // 遍历 res 的指针
13.         int cur2 = 0;                // 填充 tmp 的指针
14.         
15.         // 核心:对 res 进行行程长度编码(RLE)
16.         while (cur1 < len){
17.             int cnt = 0;             // 连续相同字符的计数
18.             char cur_char = res[cur1];// 当前要统计的字符
19.             // 统计连续相同字符的个数
20.             while (cur1 < len && res[cur1] == cur_char){
21.                 cur1++;
22.                 cnt++;
23.             }
24.             // 把「次数 + 字符」写入 tmp
25.             tmp[cur2++] = cnt + '0'; // 数字转字符:cnt + '0'
26.             tmp[cur2++] = cur_char;
27.         }
28.         tmp[cur2] = '\0';            // 给 tmp 加上字符串结束符
29.         strcpy(res, tmp);            // 把本轮编码结果拷贝回 res,作为下一轮的输入
30.     }
31.  
32.     return res; // 返回最终第 n 项
33. }

该算法的时间复杂度为O(N×L),其中N是迭代次数n,L是每一轮字符串的平均长度,空间复杂度为O(L),是本题的标准解法。

3.在编写代码的过程中有以下几点需要注意:

①在进行重复个数计数时,不要"向后比",应该"向前看"。先记住当前长什么样的字符,然后往后数有多少个和它一样的,数完同时游标也就跟着走完了。这样是最稳妥的做法,以免出现越界、死循环等情况。

②开辟内存的时候,要注意本题的字符串长度增长得非常快,所以要开辟大一些的空间。

③字符串拷贝的时候最好使用strcpy而不是memcpy,因为strcpy会自动找到'\0',并在复制完成后自动补'\0',而memcpy还需要注意额外开辟放置'\0'的空间,并且最后手动补'\0':

cpp 复制代码
1. strcpy(res, tmp);
2. memcpy(res, tmp, sizeof(char) * cur2);

4.官方还给出了一种查表的方法,因为本题输入的最大迭代次数为30,情况不算多,所以可以将所有情况全都枚举出来,根据输入的迭代次数进行查表后输出对应字符串。这种方法的时间复杂度为O(1),空间复杂度为O(C×M),其中C是N是上界,在本题中C=30,M为生成的字符串中的最大长度。属于是用空间换时间了。

相关推荐
丶小鱼丶2 小时前
数据结构和算法之【二叉树】
java·数据结构·算法
2301_793804692 小时前
模板代码安全性增强
开发语言·c++·算法
测试_AI_一辰2 小时前
Agent & RAG 测试工程笔记 13:RAG检索层原理拆解:从“看不懂”到手算召回过程
人工智能·笔记·功能测试·算法·ai·ai编程
干啥啥不行,秃头第一名2 小时前
C++中的观察者模式
开发语言·c++·算法
阿Y加油吧2 小时前
力扣打卡——反转链表、回文链表判断 题解
算法·leetcode
羊小猪~~2 小时前
算法/力扣--数组典型题目
c语言·c++·python·算法·leetcode·职场和发展·求职招聘
Johnny.Cheung2 小时前
【德国技术面试】两道小算法题(求两数之和/解谜游戏)
算法·面试
无敌昊哥战神2 小时前
LeetCode 112. 路径总和 - 避坑指南与多语言全解法(C/C++/Python)
c语言·c++·leetcode
x_xbx2 小时前
LeetCode:198. 打家劫舍
算法·leetcode·职场和发展