算法日常・每日刷题--<模拟>4

38. 外观数列 - 力扣(LeetCode)38. 外观数列 - 「外观数列」是一个数位字符串序列,由递归公式定义: * countAndSay(1) = "1" * countAndSay(n) 是 countAndSay(n-1) 的行程长度编码。 行程长度编码 https://baike.baidu.com/item/%E8%A1%8C%E7%A8%8B%E9%95%BF%E5%BA%A6%E7%BC%96%E7%A0%81/2931940(RLE)是一种字符串压缩方法,其工作原理是通过将每个最大连续相同字符组替换为该组的长度后加上该字符本身。例如,要压缩字符串 "3322251" ,我们将 "33" 用 "23" 替换,将 "222" 用 "32" 替换,将 "5" 用 "15" 替换并将 "1" 用 "11" 替换。因此压缩后字符串变为 "23321511"。给定一个整数 n ,返回 外观数列 的第 n 个元素。示例 1:输入:n = 4输出:"1211"解释:countAndSay(1) = "1"countAndSay(2) = "1" 的行程长度编码 = "11"countAndSay(3) = "11" 的行程长度编码 = "21"countAndSay(4) = "21" 的行程长度编码 = "1211"示例 2:输入:n = 1输出:"1"解释:这是基本情况。 提示: * 1 <= n <= 30 进阶:你能迭代解决该问题吗?https://leetcode.cn/problems/count-and-say/description/

题目

外观数列是一个数字字符串序列,由以下递归公式定义:

  • countAndSay(1) = "1"

  • countAndSay(n)countAndSay(n-1)行程长度编码(Run-Length Encoding, RLE)

所谓行程长度编码,就是将字符串中每个最大连续相同字符组 替换为该组的长度 + 该字符本身

例如,压缩字符串 "3322251"

  • "33""23"(2个3)

  • "222""32"(3个2)

  • "5""15"(1个5)

  • "1""11"(1个1)

最终得到 "23321511"

解法

这道题目我们采取双指针的方法

left 标记当前连续数字段起点right 不断向右滑动寻找分段边界:

  1. 相等场景 :nums[right] == nums[left] 说明是同一段重复数字,只执行 right++ 继续向后统计;
  2. 不等场景 :nums[right] !=nums[left] 找到一段的终点,计算本段数字数量 count = right - left; 拼接规则:count(个数) + s[left(当前数字)]; 再更新 left = right,开启下一段统计;再实现的过程,count非string类型,要转换,用to_string
  3. 循环直到 right 走到字符串末尾,整轮遍历完成,生成下一层外观数列。
cpp 复制代码
#include<string>
class Solution {
public:
    string countAndSay(int n) {
        string s1;
        s1+='1';
        for(int i=1;i<n;i++)
        {
            int left=0,right=0;
            int count=0;
            int x=s1.size();
            string s2;
            while(right<x)
            {
                while(right<x&&s1[right]==s1[left])
                right++;
                
                count=right-left;
                s2+=to_string(count);
                s2+=s1[left];
                left=right;
             
            }
             s1=s2;
        }
       
        return s1;
    }


};