51nod 1089 最长回文子串 V2(Manacher算法)

43 篇文章 0 订阅

 

回文串是指aba、abba、cccbccc、aaaa这种左右对称的字符串。

输入一个字符串Str,输出Str里最长回文子串的长度。

Input

输入Str(Str的长度 <= 100000)

Output

输出最长回文子串的长度L。

Input示例

daabaac

Output示例

5

 

 

 

    刚开学有点嗨,居然花了点时间才搞定这个算法,静不下来,太活泼了。

    我看了许多关于这个算法的帖子,都看不下去,get不到重点,后来静下来慢慢看才搞定。

    说下重点:(代码有注析)

    1:  为了忽略单双字符串配对,中间插入符号,为了方便判断边界,开头加入一个不一样的符号

    2:最重要的一点!!之前配对已经判断过了,算法核心就是后面算过的可能和前面区间对称,带着这个想法看理解的快一点

    看了那么多篇,这篇是对我来说好比较好理解的(个人想法):http://www.cnblogs.com/biyeymyhjob/archive/2012/10/04/2711527.html

    最后附上代码:

    

#include <iostream>
#include <algorithm>
#include <string.h>
#include <mem.h>
using namespace std;
char str1[100005],str2[200005];
int leng,i,j,dian=0,maxl=0,ans[200005],maxans=0,left,right;0
int min(int a,int b)  //返回较小的数字
{
 if(a<b)
   return a;
   return b;
}
void csh()   //初始化
{
    ans[0]=1;
    str2[0]='&';  //免去判断边界
    str2[1]='*';    
    j=2;
    for(i=0;i<leng;i++)
    {
        str2[j++]=str1[i];
        str2[j++]='*';
    }
}
void manachar()    
{
    leng=j;  //变化后的数组长度
    for(i=1;i<leng;i++)  
    {
       if(i<maxl)     //如果少于最长的边界
           ans[i]=min(maxl-i,ans[2*dian-i]);  //manachar算法思想,对称
        else ans[i]=1;             //边界外,初始为1,然后进行扩展直到不配对
        while(str2[i+ans[i]]==str2[i-ans[i]])  //一直判断直到不配对
            ans[i]++;
            if(ans[i]>maxans)    //更新长度(答案)
                maxans=ans[i];
        if(ans[i]+i>maxl)  //更新最长边界及其中心点
        {
            dian=i;
            maxl=ans[i]+i;
        }
    }
}
int main()
{
   cin>>str1;
   leng=strlen(str1);
   csh();
   manachar();
   cout<<maxans-1;   
   return 0;
}

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值