【算法】manacher
1. 算法简介#
Manacher 算法,俗称马拉车。是一个可以在线性时间复杂度内高效解决最大回文子串的问题。
2. 算法流程#
暴力想必大家也都会,就是枚举中心点然后暴力扩展长度。时间复杂度
还有就是字符串哈希 + 二分:枚举中心点,将暴力的扩展变成二分。因为长度越长更不能回文,长度越短更能回文,满足单调性。判断子串相同就用哈希即可。这样可以做到时间复杂度
最后是 manacher 算法,就是利用那些已经计算过的信息看来推导没有计算过的信息。
首先处理一下奇回文和偶回文的情况:在字符串的开头、结尾以及每一个字符之间插入一个没有在串中出现过的字符 &
或 $
或 #
,可以发现这样处理过后的字符串的最大回文串的开头结尾均为 "插入字符",原最大回文串长为新串的最大回文半径长度
对于每一个位置
,显然无法利用原有的信息,直接暴力去做。 ,找到 在全局最长回文串下对应的 位置,可以分为两类;-
- 如果
对应的区间被包含于 区间中,则 ;
- 如果
-
- 如果
对应的区间没有被包含于 区间中,则令 然后暴力匹配;
- 如果
根据下图加深理解:
- 如果
对应的区间被包含于 区间中,则 ;
- 如果
对应的区间没有被包含于 区间中,则令 然后暴力匹配;
3. 算法实现#
#include<bits/stdc++.h>
#define int long long
#define reg register
#define For(i,l,r) for(reg int i=l;i<=r;++i)
#define FOR(i,r,l) for(reg int i=r;i>=l;--i)
using namespace std;
const int N = 5e7;
int n, d[N];
char s[N];
string t = " ";
int Manacher() {
int ans = 0;
for (reg int i = 1, M = 0, r = 0; i <= n; ++i) {
if(i <= r) d[i] = min(d[2 * M - i], r - i + 1);
while(i - d[i] >= 1 && i + d[i] <= n && t[i - d[i]] == t[i + d[i]]) d[i]++;
if(i + d[i] - 1 > r) M = i, r = i + d[i] - 1;
ans = max(ans, d[i] - 1);
}
return ans;
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
cin >> (s + 1);
n = strlen(s + 1);
t += '#';
For(i,1,n) {
t += s[i], t += "#";
}
n = 2 * n + 1;
cout << Manacher() << '\n';
return 0;
}
后记#
可以拿 Z 函数和 Manacher 的关键代码进行对比:
Manacher:
for (reg int i = 1, M = 0, r = 0; i <= n; ++i) {
if(i <= r) d[i] = min(d[2 * M - i], r - i + 1);
while(i - d[i] >= 1 && i + d[i] <= n && t[i - d[i]] == t[i + d[i]]) d[i]++;
if(i + d[i] - 1 > r) M = i, r = i + d[i] - 1;
}
Z 函数:
for (reg int i = 2, l, r = 0; i <= m; ++i) {
if(i <= r) z[i] = min(z[i - l + 1], r - i + 1);
while(i + z[i] <= m && t[1 + z[i]] == t[i + z[i]]) z[i]++;
if(i + z[i] - 1 > r) l = i, r = i + z[i] - 1;
}
这俩玩意的代码简直一模一样,相似度
作者:Daniel-yao
出处:https://www.cnblogs.com/Daniel-yao/p/18554828
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具