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

来源:互联网 发布:php手机租车网站源码 编辑:程序博客网 时间:2024/06/15 09:26

回文串是指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;0int 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
原创粉丝点击