今天学习了一下manacher算法,比较难理解的是这一步,mx表示的是当前的对称子串的最右端, id表示的这个子串的中间这个点。2*id-i 表示 i 关于 id 的对称点 j
p[i]=mx>i?min(p[2*id-i],mx-i):1;
AC代码:
/* ***********************************************
Author :yzkAccepted
Created Time :2016/7/13 14:33:55
TASK :ggfly.cpp
LANG :C++
************************************************ */
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <stack>
using namespace std;
const int maxn=2100;
char s[maxn],s1[maxn];
int p[maxn];
int manacher(char *s)
{
int i;
int mx=0,id=0,mxx=-1;
memset(p,0,sizeof(p));
for(i=1;s[i]!='\0';i++){
p[i]=mx>i?min(p[2*id-i],mx-i):1;
while(s[i+p[i]]==s[i-p[i]]) p[i]++;
if(i+p[i]>mx){
mx=i+p[i];
id=i;
}
}
for(i=1;s[i]!='\0';i++){
// printf("%d ",p[i]);
if(p[i]>mxx) mxx=p[i];
}
return mxx-1;
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
gets(s1);
int n=strlen(s1),tot=1;
memset(p,0,sizeof(p));
s[0]='$';
for(int i=0;i<n;i++)
{
s[tot]='#';
tot++;
s[tot]=s1[i];
tot++;
}
s[tot]='#';
// cout<<s<<endl;
int mxx=-1;
cout<<manacher(s)<<endl;
return 0;
}
本文深入讲解了Manacher算法的核心思想及实现细节,并提供了一段完整的C++代码示例。通过解析算法中的关键步骤,帮助读者更好地理解如何寻找字符串中最长的回文子串。
1462

被折叠的 条评论
为什么被折叠?



