原题目
报数序列是一个整数序列,按照其中的整数的顺序进行报数,得到下一个数。其前五项如下:
1 1
2 11
3 21
4 1211
5 111221
1 被读作 “one 1” (“一个一”) , 即 11。
11 被读作 “two 1s” (“两个一”), 即 21。
21 被读作 “one 2”, “one 1” (“一个二” , “一个一”) , 即 1211。
给定一个正整数 n(1 ≤ n ≤ 30),输出报数序列的第 n 项。
注意:整数顺序将表示为一个字符串。
示例 1:
输入: 1
输出: “1”
示例 2:
输入: 4
输出: “1211”
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/count-and-say
题目大意
就是将每一层的数字进行读数,统计每个数连续的个数
将该数的个数和该数的值存入下一层,以此类推。
例如:
第五层:
可以看成第四层有1个连续的1,1个连续的2,2个连续的1
所以第五层为:111221
题目分析
递归法:递归到最后一次,回溯通过前一层得出下一层
也可以用递推
完整代码
char * countAndSay(int n){
char *str1=(char *)malloc(sizeof(char)*4500);
char *str2=(char *)malloc(sizeof(char)*4500);
if(n==1)
{
strcpy(str1,"1");
return str1;
}
strcpy(str1,countAndSay(n-1));//将上一层得到的字符串当作该层字符串的读取串
int i=0,len1=strlen(str1),k=1,len2=0;
//i为读取串当前字符位置,len1位读取串长度,k为连续字符个数,len2为该层字符串长度
while(i<len1)
{
if(i+1<len1&&str1[i]==str1[i+1])//如果当前字符大于后一个字符说明两者连续,用k统计
{k++,i++;}
else//将k转变为字符,放入str2中再将该读取串字符放入str2中
{
str2[len2++]=k+'0';
str2[len2++]=str1[i];
i++;//读取下一个字符
k=1;//k赋为初值
}
}
str2[len2]='\0';
return str2;
}
1.递推
class Solution {
public:
string countAndSay(int n) {
string s = "1";//初始值
string res = "1";//n为1的情况
for(int i = 1; i < n; i++){//对上一层进行操作得到下一层,以此类推
res = "";//将结果清空
for(int j = 0; j < s.size(); j++){
int count = 1;//统计每个连续数的个数
while(s[j]==s[j+1]){
count++;
j++;
}
res += to_string(count) + s[j];//统计数+连续数
}
s = res;//得到下一层后,赋值给s,来求下下层
}
return res;
}
};
2.递归
class Solution {
public:
string countAndSay(int n) {
if(n == 1)return "1";
string s = countAndSay(n-1);
string res;
int count = 1;
for(int i = 0; i < s.size(); i++){
if(s[i]==s[i+1]){
count++;
}else{
res += to_string(count)+s[i];
count = 1;
}
}
return res;
}
};