个人主页:兜里有颗棉花糖
欢迎 点赞 收藏✨ 留言✉ 加关注本文由 兜里有颗棉花糖 原创
收录于专栏【手撕算法系列专栏】【Leetcode】
本专栏旨在提高自己算法能力的同时,记录一下自己的学习过程,希望对大家有所帮助
希望我们一起努力、成长,共同进步。
原题链接:点击直接跳转到该题目
给定一个正整数 n ,输出外观数列的第 n 项。
「外观数列」是一个整数序列,从数字 1 开始,序列中的每一项都是对前一项的描述。
你可以将其视作是由递归公式定义的数字字符串序列:
countAndSay(1) = "1"
countAndSay(n) 是对 countAndSay(n-1) 的描述,然后转换成另一个数字字符串。
输入:n = 1
输出:“1”
解释:这是一个基本样例。
示例2:
输入:n = 4
输出:“1211”
解释:
countAndSay(1) = “1”
countAndSay(2) = 读 “1” = 一 个 1 = “11”
countAndSay(3) = 读 “11” = 二 个 1 = “21”
countAndSay(4) = 读 “21” = 一 个 2 + 一 个 1 = “12” + “11” = “1211”
注意:
1 <= n <= 30
本题涉及的算法:双指针、模拟。
双指针的作用如下:
left
指向当前统计字符的起始位置,右指针right向后扫描,直到找到第一个与[left, right)
区间中元素不同的位置(注意这里是左闭右开),此时区间中相同字符的个数就是right - left
,将这个结果与区间内的字符一起更新tmp
字符串,然后将左指针left
更新为当前right
所指向的位置。重复上述步骤,直到遍历原字符串中的所有字符。class Solution {
public:
string countAndSay(int n) {
string ret = "1";
for(int i = 1;i < n;i++)
{
string tmp;
int len = ret.size();
for(int left = 0,right = 0;right < len;)
{
while(ret[left] == ret[right] && right < len) right++;
tmp += to_string(right - left) + ret[left];
left = right;
}
ret = tmp;
}
return ret;
}
};
最后就顺利通过啦!!!