zoukankan      html  css  js  c++  java
  • Manacher 算法

    Manacher算法用于求回文子串,它的复杂度为O(n)。

    这个算法有一个很巧妙的地方,它把奇数的回文串和偶数的回文串统一起来考虑了。在相邻的两个字符之间加进一个分隔符 '#' ,串的首尾也要加。

    原串:abaab

    新串:#a#b#a#a#b#

    中心思想是,用一个辅助数组p记录以每个字符为中心的最长回文半径,也就是p[i]记录以s[i]字符为中心的最长回文半径。p[i]最小为1,此时回文串为s[i]本身。

    我们用MaxId记录在 i 之前的回文串中,延伸至最右端的位置,同时用id记录这个MaxId的id值。核心代码如下:

            for(i=1;i<n;i++)
            {
                if(MaxId>i)
                {
                    p[i]=min(p[id*2-i],MaxId-i);
                }
                else
                {
                    p[i]=1;
                }
                while(a[i+p[i]]==a[i-p[i]])
                {
                    p[i]++;
                }
                if(p[i]+i>MaxId)
                {
                    MaxId=p[i]+i;
                    id=i;
                }
        }

    为了防止求P[i]向两边扩展时可能数组越界,我们需要在数组最前面和最后面加一个特殊字符,令P[0]=‘$’最后位置默认为‘’不需要特殊处理。

     

  • 相关阅读:
    兑奖
    杨辉三角
    偶数求和
    进制转化
    填词
    等值数目
    Spring框架的七个模块
    数据库中的第1、2、3范式 (昨天没睡好,因为那个蚊子~~)
    关于eclipse 不编译或者找不到*.class的问题
    servlet生命周期的理解
  • 原文地址:https://www.cnblogs.com/yongren1zu/p/3234710.html
Copyright © 2011-2022 走看看