Manacher 算法是一个高效的算法,像KMP一样。
算法简介:算法的目的是在O(n)的时间复杂度内找到一个字符串中各个字母所在的最大长度的回文串。
此算法用到了一个Rad[]数组的定义,Rad[i]表示回文的半径,即最大的j满足str[i-j+1...i] = str[i+1...i+j]。
我们的工作就是把全部的Rad[]求出来。
有两个结论:
(1): 对于一个整数k,如果 (1<=k<=Rad[i] && Rad[i-k] < Rad[i]-k ) 那么, Rad[i+k] = min( Rad[i-k], Rad[i]-k ).
(2) : 对于一个整数k,如果 (1<=k<=Rad[i] && Rad[i-k] > Rad[i]-k ) 那么, Rad[i+k] = min( Rad[i-k], Rad[i]-k ).
==================================================================
模板1:
char str[M];//start from index 1
int rad[M];
void Manacher()
{
int i,j,k;
i=1;j = 0;
while(i< =n)
{
while(str[i-j] == str[i+j+1] && i-j>0 && i+j+1 < = n)
j++;
rad[i] = j;
k = 1;
while(k<=rad[i] && rad[i-k] != rad[i]-k)
{
rad[i+k] = min(rad[i-k],rad[i]-k);
k++;
}
i = i+k;
j=max(j-k,0);
}
//Rad[] has obtain the ans
}
模板2.
void pk()
{
int i;
int mx = 0;
int id;
for(i=1; i<n; i++)
{
if( mx > i )
p[i] = MIN( p[2*id-i], mx-i );
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;
}
}
}