char数组型:
int const MAX = 110005;
char s[MAX << 1];
int p[MAX << 1];
int Manacher()
{
int len = (int)strlen(s), maxp = 0, ans = 0;
for(int i = len; i >= 0; i--)
{
s[i * 2 + 2] = s[i];
s[i * 2 + 1] = '#';
}
s[0] = '*';
for(int i = 2; i < 2 * len + 1; i++)
{
if(p[maxp] + maxp > i)
p[i] = min(p[2 * maxp - i], p[maxp] + maxp - i);
else
p[i] = 1;
while(s[i - p[i]] == s[i + p[i]])
p[i]++;
if(p[maxp] + maxp < i + p[i])
maxp = i;
if(ans < p[i])
ans = p[i];
}
return ans - 1;
}
string型:
string Manacher(string s)
{
string sNew = "$#";
for (auto iter = s.cbegin(); iter != s.cend(); iter++)
{
sNew += *iter;
sNew += "#";
}
int iNewSize = (int)sNew.size();
int iMaxSubStringLength = -1; // 最长回文子串的长度
int iMaxSubStringPos = -1; // 最长回文子串中心点的位置
vector<int> p(iNewSize, 0);
int id = 0;
int mx = 0;
for (int i = 1; i < iNewSize; i++)
{
if (i < mx)
{
p[i] = min(p[2 * id - i], mx - i);
}
else
{
p[i] = 1;
}
while (sNew[i - p[i]] == sNew[i + p[i]]) // 最左边sNew[0]='$',最右边sNew[sNew.size()] = '\0',无需判断边界
{
p[i]++;
}
if (mx < i + p[i]) //我们每走一步i,都要和mx比较,我们希望mx尽可能的远,这样才能更有机会执行if (i < mx)这句代码,从而提高效率
{
id = i;
mx = i + p[i];
}
if (p[i] - 1 > iMaxSubStringLength)
{
iMaxSubStringLength = p[i] - 1;
iMaxSubStringPos = i;
}
}
auto iStart = s.cbegin() + (iMaxSubStringPos - iMaxSubStringLength - 1) / 2; // 将最长回文子串起始位置转换回原串
return string(iStart, iStart + iMaxSubStringLength);
}