最长回文子串C语言版 方法一

这道题第一次 写的时候老是堆栈出错,找不出错误,原因就是最后一句返回,如果单独把结果输出,则结果是正确的,也是很迷,搞了好久也不知道是怎么回事. 问题:就在于整个输出的时候一直报错! 不想了,但我敢肯定程序一定是正确的,因为我把自己的代码和题解对照了。

后来看题解的过程中发现,有更加省内存的方法,那就是不申请新的空间,只在原来的数组上修改。妙啊!分享出来给大家 :第二个代码段。大致思路是不变的。还是中心开花

char * longestPalindrome(char * s){
//我最先想到的就是中心开花法,因为回文意味着对称,从中间开始两边都是相等的
//但是有一个阻碍,没错,就是对于偶数个怎么办?看了看题解,评论说可以添加字符
//想了想还是有道理的,将字符之间的空隙全用*来填充,这可以完美解决,但是会有内存消耗
int length = (int)strlen(s);
if(length==1||length==0)
   {
       return s;
   }
   char * return_char=(char*)malloc(length*sizeof(char));
   int now_count=0;//目前最大长度
   bool position=true;//是否位于两个数字中间
   for(int i=0;i<length-1;)
   {    
         int j=0;
       if(position==true)
       {   
             position=false;
             while((i-j)>=0&&(i+j+1)<length)
             {
                 if(s[(i-j)]==s[(i+j+1)])
                          j++;
                  else 
                    break;
             }
             
             if(2*j>now_count)
             { 
                 now_count=2*j;
                 for(int k=0;k<now_count;k++)
                 return_char[k]=s[i-j+1+k];
             }
             i++;
             
       }
       else
       {    
              j=1;
           position=true;
           while((i-j)>=0&&(i+j)<length)
           {
               if(s[i-j]==s[i+j])
                     j++;
               else
               break;
           }
           j--;
           if(1+2*(j)>now_count)
           {
               now_count=1+2*(j);
                for(int k=0;k<now_count;k++)
                  { 
                       return_char[k]=s[i-j+k];
                   }
           }
 
       }

   }

for(int k=0;k<now_count;k++)
{
    printf("%c",return_char[k]);
}
return_char[now_count]='/0';
return(return_char);

}

魔改

char * longestPalindrome(char * s){
    int N = strlen(s), start = 0, len = 0;
    if(N==0||N==1)
    {
        return(s);
    }
    bool position = true; // N字符串长度, start子串起始位置,len子串长度
    for (int i = 0  ; i < N-1; ) {
         int left,right;   // 奇数长度的回文子串
       if(position==false) 
        {
            left = i - 1, right = i + 1;i++;
            position =true;
           }
        else
        {  left = i, right = i + 1;position=false;}
        while (left >= 0 && right < N && s[left] == s[right]){
            left--; right++;            // 以 i 为中心,向两侧延伸,直到不再满足回文
        }                               // left+1 ~ right-1 则为以i为中心的最大回文子串
        if (right - left - 1 > len) {   // 若更长,则保存该子串信息
            start = left + 1;
            len = right - left - 1;
        }
    }
    
    s[start + len] = '\0';      // 原地修改返回
    return s + start;
}

执行结果:
通过
显示详情
执行用时 :
20 ms
, 在所有 c 提交中击败了
88.48%
的用户
内存消耗 :
7 MB
, 在所有 c 提交中击败了
85.38%
的用户

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值