题目:Count and Say
The count-and-say sequence is the sequence of integers beginning as follows:
1, 11, 21, 1211, 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 sequence.
Note: The sequence of integers will be represented as a string.
思路:就是挨个遍历,用变量记录连续相同的个数,当遇到不相同的时候,保存个数和对应的字符。
第一遍做的时候,内存不够了,因为分配的空间没有及时free掉;
第二遍的时候,超时了,因为是一开始一次性地开辟了一个足够大的空间pow(2,n)+1;同时在处理的过程中又开辟一个同样大小的空间记录新的内容,最后strcpy,
这种做法特别傻。浪费空间,还没有利用指针的作用。
第三遍改良一下,一开始只是分配起码的两个空间,就是1的结果;空间最多的情况就是变成下一个字符串的长度变成当前字符串长度的2倍;
在产生新的字符串之前,保存当前字符串的长度,新开辟一个空间为(2*len+1)的长度就够了;最后把当前的字符串占用的空间free掉,同时把当前字符串的指针指向新开辟的空间,但是一定要注意,generate函数一定要把新开辟空间的字符串返回到原函数中,否则,原函数中的ret指针指向的地址一直是不变的,没有得到新开辟地址空间中的值,从而造成错误。
代码:
char* generate(char* ret);
char* countAndSay(int n) {
char* ret=(char* )malloc(sizeof(char)*2);
memset(ret,'\0',2);
for(int i=1;i<=n;i++)
{
ret=generate(ret);
}
return ret;
}
char* generate(char* ret)
{
//先得到ret的长度
int len=strlen(ret);
int i=0;
if(len==0)
{
ret[i]=1+'0';
ret[i+1]='\0';
}
else
{
char start=ret[0];
int number=0;
char* tmp=(char*)malloc(sizeof(char)*(2*len+1));
memset(tmp,'\0',2*len+1);
int tmpStart=-1;
for( i=0;i<len;i++)
{
if(start == ret[i]) number++;
else //出现不相等的情况
{
tmp[++tmpStart]=number+'0';
tmp[++tmpStart]=start;
start=ret[i];
i--;
number=0;
}
}
if(i>=len)
{
tmp[++tmpStart]=number+'0';
tmp[++tmpStart]=start;
}
tmp[tmpStart+1]='\0';
free(ret); //把以前ret指向的字符串空间free掉
ret=tmp;//指向新开辟的空间
}
return ret; //一定要返回,否则原函数中的ret所指向的字符串不变
}