字符串--manacher

manacher

manacher可以在(O(n))的时间内求解一个字符串的最长回文子串长度

朴素的做法:

枚举区间左右端点(l)(r),判断([l,r])是否回文,时间复杂度(O(n^3))

优化:

枚举回文中心,分别左右扩展,时间复杂度(O(n^2))

再优化

利用了回文的左右两边相等的性质

code

char str[maxn*2];

int p[maxn*2];        //回文半径数组

int init(char *s)           //str数组初始化
{
    int len = strlen(s);
    int k = 0;              //str数组的长度,最后会等于len*2+2
    str[k++] = '@';         //开头加个特殊字符
    for(int i = 0; i < len; i++)
    {
        str[k++] = '#';
        str[k++] = s[i];
    }
    str[k++] = '#';
    str[k] = 0;             //末尾也要不一样,给什么都行
    return k;
}

int manacher(char *s)
{
    int len = init(s);          //str的数组长度
    int mx = 0,id = 0;          //以id为中心可以扩展到的最右边界mx
    int ans = 0;                //回文长度
    for(int i = 0; i < len; i++) 
    {
        if(mx > i) p[i] = min(mx-i,p[2*id-i]);                    //如果i小于mx
        else p[i] = 1;

        while(str[i + p[i]] == str[i-p[i]]) p[i]++;            //以i为中心扩展

        if(p[i]+i > mx)                                            //更新mx
        {
            mx = p[i] + i;
            id = i;

            ans = max(ans,p[i]);
        }
    }
    return ans-1;
}
原文地址:https://www.cnblogs.com/hezongdnf/p/12196471.html