38. Count and Say

题目: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所指向的字符串不变
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值