力扣精选100道——外观数列(模拟专题)

外观数列算法题链接

🚩了解题意

该题的下面充分的给你说明了这个题目的意思。 3  3  2  2   2   5   1 我们根据我们正常读的顺序读

俩个3 三个2 一个5 一个1

连起来就是 2 3  3  2  1  5  1 这就是最终输出的字符串。

题目开头说了,我们最初是 1开始读取。

样例是n=4,
那么我们读取4是 1211,我们读取1 只有一个1 
那么2对应的值就是11(1个1的转换),
那么3就是21(2个1的转换),
4就是1211(一个2一个1的转换)

如果遇到连续相同的数字 ,我们需要总读,如果1112,我们不能三个1分开读,一个1一个1一个1一个2,这样的结果不还是1112吗,不能重复读,我们需要将连续相同的1的个数先弄清楚,1112中连续相同的1是三个,2是单独就1个。如果出现11123311,这种1不是连续的我们不用加,我们只要连续相同的,不是连续的后续出现了相同的数字也是分开读了。 

所以11123311 应该读成 3个1 一个2 俩个3 俩个1.


🚩算法原理

其实从上面了解题意的过程中,我们发现一个地方

如果遇到连续相同的数字 ,需要将连续相同的数字对应的个数相加然后读。

我们针对n=5来进行思考,一组数组,我们看到有三个1,那么我们就需要写成【3 1】,然后继续接下来是2个2 ,我们就得写成【2 2】,后面是1个1,我们学成【1 1】.我们注意到,最终得到的【】花括号里前面一个数是连续相同数字的个数,后面一个数是当前的数字

前面一个数是记录连续相同数字的个数,后面的数是记录当前的数,那么我们这一题很明显是用双指针,left和right都是从0开始,遇到相同的数,right++,直到遇到不同的数,我们获取的连续相同的数字长度是right-left,然后left对应的值就是【】右边代表当前的数字,right-left就是几个,left对应的值就是几,几个几,就是这样读。然后left直接更新到right即可,然后继续循环,直到right大于这个字符串的长度即可。

right一直++,遇到right对应的值不等于left对应的值的时候,我们就更新结果,本题是数字字符,需要用到to_string将数字转成字符串,right-left=3转换成 "3",然后记录left对应的值,"3"+"1";

此时我们将left移到right对应的位置进行继续让right继续++判断。


我们的right不能一直++,到了字符串长度截至,所以我们再判断的时候,也需要加上right的移动范围的限制。


🚩实现代码

class Solution {
public:
    string countAndSay(int n) {
        string ret="1";//起初设置字符串是1
        for(int i=1;i<n;i++)
        {
            string tmp;//设置临时的字符串
            for(int left=0,right=0;right<ret.size();)
            {
                while(right<ret.size() && ret[left]==ret[right])right++;
                //如果left和right对应的值相等,那么right++
                tmp+=to_string(right-left)+ret[left];
                //直到不相等,我们就将数字转字符right-left代表有几个相同的,再加上ret的left对应的值
                left=right;//然后将right给left继续循环
            }
            ret=tmp;
        }
        
        return ret;
    }
};

前行的路上,永远做自己光。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值