题目链接:hdu4763
题面
题目大意
找到字符串中的最长公共前后缀,并且这个前后缀的字串在除了前后缀的中间部分也要存在这个子串。例如:EAEBE,其中,E 表示这个子串,输出 E 的最大长度,如果不存在输出 0 。
解题思路
KMP
利用求失配函数得到串的最长公共前后缀,然后从 2i 的位置到 len-i 的位置开始枚举中间是否存在子串,判断条件是: f a i l [ j ] = = i fail[j]==i fail[j]==i。含义是失配指针能够索引到公共前缀后一个位置,然后从 j 位置到达 i 表示 0 - j 有两个相同的串。由于要找到最长的答案,所以我们从大到小枚举 i 。
时间复杂度 O ( n + k n ) O(n + kn) O(n+kn),空间复杂度 O ( n ) O(n) O(n)。
实现代码
#include <cstdio>
#include <cstring>
const int maxn = (int)1e6+5;
char str[maxn];
int fail[maxn], len;
int main() {
int T, i, j, res;
scanf("%d", &T); getchar();
while (T--) {
gets(str);
len = strlen(str);
i = 0, j = -1;
fail[0] = -1;
while (i < len) {
if (j == -1 || str[i] == str[j]) {
i++; j++;
fail[i] = j;
} else {
j = fail[j];
}
}
res = 0;
for (i=fail[len]; i; i=fail[i]) {
for (j=i<<1; j+i<=len; j++) {
if (fail[j] == i) {
res = i;
break;
}
}
if (res) break;
}
printf("%d\n", res);
}
return 0;
}