马拉车(Manacher)算法是一种时间复杂度为O(n)的求字符串中的最大回文子串的算法,
他很好的利用了回文串是关于中间字符对称的特点进行了剪枝操作,把时间复杂度优化到了O(n),并且它可以无差别处理奇偶字符串。
墙裂建议配合B站视频食用
UESTCACM 每周算法讲堂 manacher算法1(原理和思想)
UESTCACM 每周算法讲堂 manacher算法2(代码与实现)
我比较推荐看下面那个代码与实现,对着题边敲边讲,还是挺容易理解,如果看了这两个视频还是不理解的话,那就看看这个博客吧 —> Manacher Algorithm 马拉车算法(感谢博主) <— 或者也可以先看这个博客再去看视频。
其实最关键的就是下面的这些
图一
图二
一、mx > i
假设当前遍历到字符串的位置i,由于在遍历到id位置的时候已知最大回文子串,位置i还在上一个最大回文子串的范围内,所以可以利用其镜像认为,位置i以id为中心镜像到另一边的位置j是对等的。 在mx>i的条件下,又分为以下两种情况:
1. mx - i > p[j] (图1)
此时,以j为中心的回文子串包含在以id为中心的回文子串内,由于i和j位置对等,所以以i为中心的回文子串包含在以id为中心的回文子串内,所以p[i] = p[j] = p[2 * id - i]。
2. mx - i <= p[j] (图2)
此时,以j为中心的回文子串超过了以id为中心的回文子串边界,但是由于i和j位置对等,绿框部分还是相同的。所以其向右延伸的范围最大就是mx-i,剩下超过的部分谁也不能保证是否一致,只能通过循环对比判断,所以p[i] = mx - i。
二、mx < i
此时镜像对预判位置起不到作用,只能从长度为1开始对比,所以p[i] = 1。
然后我就直接附上板子了。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 3e3;
char s[