[PAT解题报告] Longest Symmetric String
最长回文子串。
长度不大,1000,可以采用暴力方法解决。时间复杂度O(n2)——即选取中心位置——可能是一个字符,也可能是两个字符之间,看向左和右能延伸的最大长度。相当于枚举所有长度位奇数和偶数的回文串。
还有注意字符串有空白,如果用C输入的话要用gets,不能用scanf。
代码:
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
using namespace std;
char s[1024];
int main() {
gets(s);
int n = strlen(s);
int answer = 0;
for (int i = 0; i < n; ++i) {
int len = 0;
for (len = 1; (i - len >= 0) && (i + len < n) && (s[i - len] == s[i + len]); ++len)
;
answer = max(((len - 1) << 1) | 1, answer);
for (len = 0; (i - len >= 0) && (i + len + 1 < n) && (s[i - len] == s[i + len + 1]); ++len)
;
answer = max(len << 1, answer);
}
printf("%d\n",answer);
return 0;
}
另外一个线性的算法叫做Manacher,写起来也不难,有兴趣的读者可以查阅Manacher算法相关的资料。
代码:
#include <string>
#include <cstring>
#include <vector>
#include <cstdio>
using namespace std;
char S[1024];
int run(char *S, int n) {
string s = "#";
for (int i = 0; i < n; ++i) {
s += S[i];
s += "#";
}
n = s.length();
int center = 0, right = 0,answer = 0;
vector<int> p;
p.resize(n);
for (int i = 0; i < n; ++i) {
int ii = (center << 1) - i;
for (p[i] = (i < right)?min(p[ii], right - i):0; (i - p[i] - 1 >= 0) && (i + p[i] + 1 < n) && (s[i - p[i] - 1] == s[i + p[i] + 1]); ++p[i])
;
if (i + p[i] > right) {
right = i + p[i];
center = i;
}
answer = max(answer, p[i]);
}
return answer;
}
int main() {
gets(S);
printf("%d\n",run(S, strlen(S)));
return 0;
}
原题链接: http://www.patest.cn/contests/pat-a-practise/1040
