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

6.5 模拟专题:LeetCode 38. 外观数列

1. 题目链接

LeetCode 38. 外观数列


2. 题目描述

给定一个正整数 n,生成外观数列的第 n 项。外观数列的定义如下:

  • 1 项为 "1"
  • n 项是对第 n-1 项的描述。例如,第 2 项描述第 1 项("1")为 "11"(即“1个1”),第 3 项描述第 2 项("11")为 "21"(即“2个1”),依次类推。

示例

  • 输入:n = 4 → 输出:"1211"
  • 输入:n = 5 → 输出:"111221"

3. 示例分析
  1. 基础案例

    • n=1"1"
    • n=2"11"
    • n=3"21"
    • n=4"1211"(描述 "21" 为“1个2,1个1”)
    • n=5"111221"(描述 "1211" 为“1个1,1个2,2个1”)
  2. 复杂案例

    • n=6"312211"(描述 "111221" 为“3个1,2个2,1个1”)

4. 算法思路

核心思想迭代生成 + 双指针统计

  1. 初始化:从第 1"1" 开始迭代。
  2. 迭代生成:对当前项从左到右扫描,统计连续相同字符的数量。
  3. 双指针统计
    • left 指针标记当前字符的起始位置。
    • right 指针向右移动,直到遇到不同字符。
    • 统计长度 right - left,拼接成新字符串的 "数量+字符"
  4. 循环递推:重复上述过程 n-1 次,生成第 n 项。

时间复杂度

  • 外层循环 n-1 次,内层遍历字符串长度,总时间复杂度为 O(n·m),其中 m 为字符串的平均长度。

5. 边界条件与注意事项
  1. 输入范围
    • n ≥ 1,需处理 n=1 直接返回 "1"
  2. 字符串拼接优化
    • 使用 string+= 操作拼接字符,避免频繁创建新对象。
  3. 指针越界检查
    • 内层循环需确保 leftright 不超过字符串长度。
  4. 大数问题
    • n 较大时(如 n=30),生成的字符串长度可能超过 1e5,需注意内存限制。

6. 代码实现
class Solution {
public:
    string countAndSay(int n) {
        string ret = "1";
        for (int i = 1; i < n; i++) { // 迭代生成前n-1项
            string tmp; // 临时存储当前项的下一项描述
            int len = ret.size();
            for (int left = 0, right = 0; right < len;) {
                // 移动right指针,统计连续相同字符的数量
                while (right < len && ret[right] == ret[left]) right++;
                // 拼接"数量+字符"
                tmp += to_string(right - left) + ret[left];
                left = right; // 更新left指针到下一个字符的起始位置
            }
            ret = tmp; // 更新当前项
        }
        return ret;
    }
};

在这里插入图片描述


关键代码解析

  1. 外层循环控制迭代次数

    for (int i = 1; i < n; i++)
    
    • 从第 1 项开始,生成到第 n 项需要迭代 n-1 次。
  2. 双指针统计连续字符

    while (right < len && ret[right] == ret[left]) right++;
    
    • right 指针右移,直到遇到不同字符或越界。此时 right - left 即为连续字符的数量。
  3. 拼接描述字符串

    tmp += to_string(right - left) + ret[left];
    
    • 将数量转换为字符串,并与当前字符拼接。例如,连续 2'1' 拼接为 "21"
  4. 更新指针位置

    left = right;
    
    • left 移动到下一个待统计字符的起始位置。

与其他解法的对比

方法时间复杂度空间复杂度核心思想
递归法O(n·m)O(n·m)递归生成前一项,再描述
迭代法O(n·m)O(m)双指针遍历,直接构造
动态规划法O(n·m)O(m)存储中间结果,避免重复计算

总结

迭代法通过双指针高效统计连续字符,避免了递归的栈空间开销,是本题的最优解。其核心在于 逐层递推双指针滑动窗口,以线性时间复杂度生成外观数列。

适用场景

  • 需要快速生成较大 n 值的结果(如 n ≤ 30)。
  • 内存敏感场景,避免递归栈溢出。

关键点

  • 理解双指针在统计连续字符中的应用。
  • 掌握字符串拼接的优化技巧。

相关文章:

  • 基于 mxgraph 实现流程图
  • VS操作快捷键系统快捷键
  • [AI绘图] ComfyUI 局部重绘(Inpainting)Workflow 绘制教程
  • 两头文件互引问题解决(前置声明)
  • 系统思考—第五项修炼
  • Java地图坐标查询距离内经纬度范围,及距离大小
  • Android面试之算法总结
  • Azure SDK 使用指南
  • 如何保障kafka的数据不会重复消费呢,如何防止漏掉呢
  • Es结合kibana查询
  • PyTorch量化技术教程:第一章 PyTorch基础入门
  • 如何在 Windows 上安装并使用 Postman?
  • 问题:md文档转换word,html,图片,excel,csv
  • SICAR标准 汽车焊装生产线触摸屏操作说明
  • LeetCode 第25、27、28题
  • 动态合并任意连续相同行
  • Linux 创建用户和用户组,设置主目录
  • vue中实现元素在界面中自由拖动
  • Flink介绍与安装
  • 4.(vue3.x+vite)接入echarts
  • 消费维权周报丨上周涉汽车类投诉较多,涉加油“跳枪”等问题
  • 浙江推动人工智能终端消费:家居机器人纳入以旧换新补贴范围
  • 中美博弈新阶段,这个“热带中国”火了
  • 中国田径巡回赛西安站完赛:男子跳远石雨豪夺冠
  • 英国知名歌手批政府:让AI公司免费使用艺术家作品是盗窃
  • 特写|银耳种植“北移”到沧州盐山,村民入伙可年增收4万元