Manacher
-算法
int MaxLcpsLength(const string& s){
if(s.empty()){
return 0;
}
string str=GetManacherString(s);
int C{-1};//最大回文半径的中点
int R{-1};//最大右边界的下一位置,方便写
//最长回文半径数组,保存了每个位置的最长回文半径
vector<int> pArr(str.size());
int Max=INT_MIN;
//求每个位置的最长回文子串
for(int i=0;i<str.size();++i){
//先求出最小的回文半径,三种情况放一块了,2*C-i是对称的i'位置,因为对称点距离左右两个边界偏移是相同的,R-i是i位置距离R的最大回文半径,二者取小
pArr[i]=R>i?min(pArr[2*C-i],R-i):1;
//pArr[i]是i位置的最小回文半径,i+pArr[i]就是下一个待比对的字符
while(i+pArr[i]<str.size() &&i-pArr[i]>-1){
//同样也是四合一
if(str[i+pArrp[i]]==str[i-pArr[i]]){
pArr[i]++;
}
else{
break;
}
}
//i+pArr[i]实际是最大右边界的下一个字符,比如i为8,pArr[i]=3;说明最大右边界实际为10,因为这里算上8,下一位置就是i+pArr[i]=11
if(i+pArr[i]>R){
R=i+pArr[i];
C=i;
}
Max=max(pArr[i],Max);
}
//因为Max是包含多余字符的最长回文半径,Max-1就是源字符串的最长回文长度
return Max-1;
}Last updated