manacher(马拉车算法)

本文深入讲解Manacher算法,一种高效求解最长回文子串问题的方法。通过利用回文串的对称特性,Manacher算法能在O(n)的时间复杂度内解决这一问题,避免了传统方法的高时间成本。文章详细解释了算法的核心思想与实现步骤,包括如何通过预处理字符串以适应不同类型的回文串,以及如何通过动态规划的方式快速确定每个位置的最长回文子串长度。

manacher

用法O(n)求最长回文子串

对于回文串有两种情况:

  1. 对于中间一个元素对称;
  2. 对于中间一个空格对称;
    为了两种情况的适应性,我们可以把他们总结归纳以下,对于第二种的我们直接加入一个不存在的元素表示空格,对于第一种显然是没有影响的,而且可以发现,这时候回文串的长度等于当前元素能扩展到的最长距离,因为对于i的左边一共有len/2个元素,右边一共有len/2个空格,即证;
    思想利用回文串的特性(以中间一个元素对称),我们每一次考虑第i个元素时,可以通过看这个元素是否在一个回文串里面,如果在,那么就先找到与他对称的那个元素进行比较,直接得到最小的回文长度,然后对这个长度进行一次比较(超过之前覆盖当前元素i的回文的话就无效了),看是否符合条件不在的话就直接暴力扩展。

核心部分

            int cur=(i>pos+vis[pos])?0:min(vis[2*pos-i],pos+vis[pos]-i);//上面黄色部分

基本代码

        for(i=0;i<=2*len+1;i++)
        {
            a[i]='#';
        }
        for(i=0;i<len;i++) a[i*2+1]=s[i];
        len=i*2+1;
        int pos=0,ans=0;
        for(i=0;i<len;i++)
        {
            int cur=(i>pos+vis[pos])?0:min(vis[2*pos-i],pos+vis[pos]-i);
            while(1){
                if(a[i-cur]!=a[i+cur]||(i-cur<0||i+cur>len)) break;
                else cur++;//暴力扩展
            }
            cur--;
            if(cur+i>pos+vis[pos]) pos=i;//更新最远回文串控制区域
            vis[i]=cur;
            ans=max(ans,cur);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值