马拉车算法细致讲解
马拉车算法的作用
- 查找一个字符串的最长回文子串的线性方法
- 算法时间复杂度: O ( n 2 ) O(n^2) O(n2)
这里就借用大佬的博客了:
一文让你彻底明白马拉车算法
这里是用的java的方法,但是讲解的很细致,认真看能清楚马拉车的内部原理。
想看c++代码的话,可以去看这个大佬的代码:
Manacher(马拉车)算法详解
两个大佬的代码都很牛。
下面是我的代码,个人实测正确,可以直接拿来当板子
测试题目:洛谷 P3805 【模板】manacher
#include<bits/stdc++.h>
//#define int long long
using namespace std;
int p[200000004];
const int N = 1e6+5;
int arr[N];
string get_new_str(string str)
{
string new_str = "^#";
for(int i = 0; i < str.size(); i ++)
{
new_str += str[i];
new_str += '#';
}
return new_str;
}
int manacher(string str)
{
int center = 0;
int right = 0;
int max_lenth = -1;
string new_str = get_new_str(str);
int x = 0;
for(int i = 1; i < new_str.size(); i++)
{
if(i < right)
p[i] = min(right-i,p[center * 2 - i]);
else p[i] = 1;
while(new_str[i-p[i]] == new_str[i + p[i]])
p[i] ++;
if(i + p[i] > right)
{
center = i;
right = center + p[i];
}
max_lenth = max(max_lenth,p[i]-1);
if(max_lenth == p[i]-1)
{
x = i;
}
}
return max_lenth;
// 下面是计算最长回文字符串,如果有两段相同的字符串的话,输出最后一个。
// 用这个模板的话,需要修改一下函数的返回类型,修改为string。
// string ans;
// for(int i = x - max_lenth; i <= x + max_lenth; i++)
// {
// if(new_str[i] == '#') continue;
// ans += new_str[i];
// }
// return ans;
}
void solve()
{
string str;
cin >> str;
cout << manacher(str) << endl;
}
signed main (void)
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int T = 1;
// cin >> T;
while(T--)
solve();
return 0;
}