馬拉車(Manacher)算法是一種時間複雜度爲O(n)的求字符串中的最大回文子串的算法,
他很好的利用了迴文串是關於中間字符對稱的特點進行了剪枝操作,把時間複雜度優化到了O(n),並且它可以無差別處理奇偶字符串。
牆裂建議配合B站視頻食用,我愛死這破站了
UESTCACM 每週算法講堂 manacher算法1(原理和思想)
UESTCACM 每週算法講堂 manacher算法2(代碼與實現)
我比較推薦看下面那個2,對着題邊敲邊講,還是挺容易理解,如果看了這兩個視頻還是不理解的話,那就看看這個博客吧 —> Manacher Algorithm 馬拉車算法(感謝博主) <— 或者也可以先看這個博客再去看視頻。
然後我就直接附上板子了。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 3e3;
char s[maxn],str[maxn];
int len1,len2,p[maxn];
void manacher()
{
int id = 0,mx = 0;
for(int i = 1; i< len2; i++)
{
if(mx > i) p[i] = min(p[2*id-i],mx-1);
else p[i] = 1;
for(; str[i+p[i]] == str[i-p[i]]; p[i]++);
if(p[i] + i > mx)
{
mx = p[i]+i;
id = i;
}
}
}
void init()
{
str[0] = '$';
str[1] = '#';
for(int i = 0; i < len1; i++)
{
str[i*2+2] = s[i];
str[i*2+3] = '#';
}
len2 = len1*2+2;
str[len2] = '*';
}
int main()
{
int n;
cin >> n;
while(n--)
{
cin >> s;
len1 = strlen(s);
init();
manacher();
int ans = 0;
for(int i = 0; i < len2; i++)
{
ans = max(ans,p[i]);
}
cout << ans-1 << endl;
}
return 0;
}