复杂算法介绍[3]-Manacher算法

复杂算法介绍[3]-Manacher算法

  Manacher算法,江湖人称马拉车算法,用来解决最长会问串问题,举个例子:

假设字符串是
   fabccba
 
最长回文串就是abccba

  如何快速求出这个最长的回文串

1、暴力尝试

  寻找以每个字符为中心的最长回文子串,但是回文子串有奇数和偶数的区分,例如回文串abccba的中轴线是在两个c中间,并不是独立的字符,为了统一奇数偶数的情况,需要对字符串进行补长变成:#f#a#b#c#c#b#a#,也就是每个字符串前面都补了一个#,字符串最后也补一个#,补出的#就是之前看不见的中轴线,现在计算以每个字符为中心的最长回文串,就能覆盖回文串长度为偶数情况,如果回文串长度为基数,由于原有字符两侧补的都是#,每个字符两侧补上#后不影响回文性质,且最长回文串就是新串最长回文串的一半,由于需要遍历以每个字符为中心的字符串,所以时间复杂度为:O(N²)

  Manacher算法就是用来优化这个流程,让时间复杂度能达到O(N)

2、 Manacher算法

  先明确几个基本概念【假设原字符串str1补上#后变成str】:

  • 1)、构造pAr数组,数组中的第i个元素表示以字符串str第i个字符为中心的最长回文半径【回文半径就是以i为中心,到回文左边界或者右边界的距离,a的回文半径是1,a#a中#的回文半径是2】
  • 2)、回文右边界R【不一定是最长的】
  • 3)、回文右边界对应的中心点C

  初始R=-1,C=-1代表无效位置

  对于任意时刻的扫描位置I(字符串的第i个字符),会有两种情况

  • 1)、I>R,即i的位置大于回文最右边界,此时只能和暴力尝试一样,扫描仪I为中心的最长回文串,并更新对应变量值
  • 2)、I<=R,我们重点讨论这种情况

  I<=R时,假设现在字符串被切割成如下结构:
在这里插入图片描述

  假设回文左侧边界是L,右侧是R,由于I在回文右侧内部,所以I字符关于c肯定有一个对称字符I’,如下图:
在这里插入图片描述

  以位置I’为中心的最长回文子串回文半径存储在pAr数组中,可以直接拿到pAr[I’],会有以下几种情况:

  • 1)、假设以I’为中心的最长回文串不会超过此时回文左侧的左边界,那么对应的以I为中心的回文串就不会超过回文右侧的右边界,也不可能成文最长的回文子串
    图如下,草绿色的就是以I’为中心的最长回文串

    在这里插入图片描述

  由于两边对称,所以I两侧也是一样,如下图,最长回文串长度就直接可以取I’的值
在这里插入图片描述

  • 2)、当以I’为中心的最长回文串超过此时回文左侧的左边界,如以下情况在这里插入图片描述

  由于以C为中心的回文串两边对称,我们一眼就能保证I左右两侧的回文大小如下
在这里插入图片描述

  有没可能I的最长回文串,超过右边界?,出现下图粉色的匹配区域:
在这里插入图片描述

  答案是不可能,证明如下:

因为

A = B逆序
A = E逆序  ===》B=E

假设存在图中粉色区域

那么
E=F逆序=B

所以以C为中心的最长回文串的右边界应该在F字符串的结束,和原始假设不符,所以当I’的回文半径超过L时,I最长回文子串边界只能是R
  • 3)、当以I’为中心的最长回文串刚好等于此时回文左侧的左边界,那么一I为中心的回文串是否有可能超过右边界?答案是可能,还是以上面有粉红色区域的图为例,因为:A = E逆序,如果存在F使得E逆序=F,可以得出A=F,并不会扩展C为中心的最长回文串边界,不会违反大前提,所以就需要确定以I为中心的最长回文串,但是草绿色区域已经明确是回文,所以下一次匹配德位置从R+1位置开始即可

  最终返回的就是pAry最大值-1,可以自己搞个字符串对应下

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值