做法一
思路: 暴力枚举每一个位置i,找到以i为对称中心的最长对称字串即可。
坑点: 如果测试点2,3没过,可能只判断了奇数长度的对称字串,忽略了偶数长度的对称字串。
代码:
#include <bits/stdc++.h>
using namespace std;
int main ()
{
string s;
getline (cin, s);
int res = 0;
for (int i = 0; i < s.length (); i ++)
{
//判断奇数长度的对称字串
int l = i, r = i;
while ((l - 1) >= 0 && (r + 1) < s.length () && s[l - 1] == s[r + 1])
{
l --;
r ++;
}
res = max (res, r - l + 1);
//判断偶数长度的对称字串
l = i + 1, r = i;
while ((l - 1) >= 0 && (r + 1) < s.length () && s[l - 1] == s[r + 1])
{
l --;
r ++;
}
res = max (res, r - l + 1);
}
cout << res;
return 0;
}
做法二
思路: 最长对称字串也就是最长的回文串长度,跑一遍马拉车算法模板即可。
代码:
#include <bits/stdc++.h>
using namespace std;
const int N = 2e7 + 10;
char a[N], b[N];
int p[N]; //p[i]表示以b[i]为对称轴的半径长度
int n, cnt;
void init ()
{
int k = 0;
b[k ++] = '$'; b[k ++] = '#';
for (int i = 0; i < n; i ++)
{
b[k ++] = a[i];
b[k ++] = '#';
}
b[k ++] = '^';
n = k;
}
void manacher ()
{
int mr = 0, mid;
for (int i = 1; i < n; i ++)
{
if (i < mr) p[i] = min (mr - i, p[mid * 2 - i]);
else p[i] = 1;
while (b[i - p[i]] == b[i + p[i]]) p[i] ++;
if (i + p[i] > mr)
{
mr = i + p[i];
mid = i;
}
}
}
int main ()
{
string s; getline (cin, s);
for (int i = 0; i < s.length (); i ++)
a[i] = s[i];
n = strlen (a);
init ();
manacher ();
int res = 0;
for (int i = 1; i < n; i ++)
res = max (res, p[i]);
cout << res - 1;
}