TiTle:
The count-and-say sequence is the sequence of integers with the first five terms as following:
1. 1 2. 11 3. 21 4. 1211 5. 111221
1
is read off as "one 1"
or 11
.11
is read off as "two 1s"
or 21
.21
is read off as "one 2
, then one 1"
or 1211
.
Given an integer n, generate the nth term of the count-and-say sequence.
Note: Each term of the sequence of integers will be represented as a string.
Example 1:
Input: 1 Output: "1"
Example 2:
Input: 4 Output: "1211"
这道题题目难以理解:
题意是n=1时输出字符串1;n=2时,数上次字符串中的数值个数,因为上次字符串有1个1,所以输出11;n=3时,由于上次字符是11,有2个1,所以输出21;n=4时,由于上次字符串是21,有1个2和1个1,所以输出1211。依次类推,写个countAndSay(n)函数返回字符串。
第一想法是递归,给定上一个输出下一个,利用递归是代码量最少的方法。
Solution:
char* generate (char* s,int n, int count) {
char* a=(char*)malloc(sizeof(char)*100000);
int i=0;
int cnt=1;
char tmp[3];
int index=0;
if (count==n)
return s;
while (s[i]!=0) {
if (s[i]==s[i+1]) {
cnt++;
i++;
}
else {
a[index++]=cnt+'0';
a[index++]=s[i];
i++;
cnt=1;
}
}
a[index]=0;
return generate(a,n,count+1);
}
char* countAndSay(int n) {
return generate("1",n,1);
}
第二,也可以非递归。直接利用n的大小进行while循环即可。
#define maxn 10005
char s[maxn], t[maxn];
char* countAndSay(int n) {
strcpy(s, "1");
strcpy(t, "");
int cnt = 1;
char tmp[3];
for(int i = 2;i <= n;i++){
int len = strlen(s);
for(int j = 0;j < len;j++){
if(s[j] == s[j + 1]){
cnt++;
}else {
tmp[0] = cnt + '0';
tmp[1] = s[j];
tmp[2] = '\0';
strcat(t, tmp);
cnt = 1;
}
}
strcpy(s, t);
strcpy(t, "");
}
return s;
}
上面这种方法利用了strcpy,strcat等c语言库函数,所以耗时较多。有人写出了不用任何库函数的方法,耗时很少,方法如下:
char* countAndSay(int n) {
char* seq=(char*)malloc(sizeof(char)*100000);
char* bak=(char*)malloc(sizeof(char)*100000);
char* tmp;
char t;
int top=1,i,index,num,l,r;
seq[0]='1';seq[1]=0;
while(--n){
index=0;
for(i=0;i0){
bak[index++]=num%10+'0';
num/=10;
}
r=index-1;
while(l