求最长回文串(Manacher算法)

来源:互联网 发布:阿里巴巴淘宝城 编辑:程序博客网 时间:2024/06/05 04:58

O(n)效率的字符串求最长回文串,感觉这个blog上写的很详细:http://www.open-open.com/lib/view/open1419150233417.html

有几个要点:

1、先要将字符串扩展成2*l+1长度的,在每两个字符之间要加上一个用不到的字符,比如‘#’,方便处理偶数回文串。

2、在扩展后的字符串两端要加一些特殊字符,防越界。

3、ra[i]数组表示以i为中点的最长回文串,mx表示以j(1<=j<i)为中心的回文串所能达到的在该字符串中的位置,po来记录达到最远位置的回文串的中心位置。

(证明ra[i]-1即为原字符串的回文串的长度的证明:http://wenku.baidu.com/view/3031d2d3360cba1aa811da42.html)

代码附上

#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<algorithm>#include<cmath>using namespace std;const int maxn=1000012;char s[maxn];char tmp[maxn<<1];int ra[maxn<<1];int INIT(char *st){    int i,len=strlen(st);    tmp[0]='@';    for (i=1;i<=2*len;i+=2)    {        tmp[i]='#';        tmp[i+1]=st[i/2];    }    tmp[2*len+1]='#';    tmp[2*len+2]='$';    tmp[2*len+3]=0;    return 2*len+1;}int MANACHER(char *st,int len){    int mx=0,ans=0,po=0;    for (int i=1;i<=len;i++)    {        if (mx>i)            ra[i]=min(mx-i,ra[2*po-i]);        else  ra[i]=1;        while (st[i-ra[i]]==st[i+ra[i]]) ra[i]++;        if (ra[i]+i>mx)        {            mx=ra[i]+i;            po=i;        }        ans=max(ans,ra[i]);    }    return ans-1;}int main(){    int T;    scanf("%d",&T);    getchar();    while (T--)    {        int ans,l;        gets(s);        l=INIT(s);        printf("%d\n",MANACHER(tmp,l));    }    return 0;}

可以去hihoCoder 1032交:https://hihocoder.com/problemset/problem/1032

0 0
原创粉丝点击