给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度.
回文就是正反读都是一样的字符串,如aba, abba等
Input输入有多组case,不超过120组,每组输入为一行小写英文字符a,b,c...y,z组成的字符串S
回文就是正反读都是一样的字符串,如aba, abba等
两组case之间由空行隔开(该空行不用处理)
字符串长度len <= 110000Output每一行一个整数x,对应一组case,表示该组case的字符串中所包含的最长回文长度.
Sample Input
aaaa ababSample Output
4
3
import java.util.*;
public class Main {
static int maxn = 110000 + 2000;
static char[] new_s = new char[maxn*2];
static int[] p = new int[maxn*2];//p[i],表示以i为中心的最长回文的半径
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
while (in.hasNext()) {
Arrays.fill(new_s, '#');
Arrays.fill(p, 0);
String s = in.next();
Manacher(s);
}
}
private static void Manacher(String s) {
int len = init(s);
int max_len = 0;
int id = 0;
for (int i = 1; i < len; i++) {
if (p[id] + id > i) {
p[i] = Math.min(p[id*2 - i], p[id] + id - i);//id*2 - i 是i关于id的对称点
}
else {
p[i] = 1;
}
while (new_s[i - p[i]] == new_s[i + p[i]]) {//一直更新p[i],直到以i为中心的半径不再增加
p[i]++;
}
if (p[id] + id < p[i] + i) id = i;//更新id
max_len = Math.max(max_len, p[i] - 1);//更新最大长度
}
System.out.println(max_len);
}
private static int init(String s) {
int len = s.length();
new_s[0] = '$';
new_s[1] = '#';
int j = 2;
for (int i = 0; i < len; i++) {
new_s[j++] = s.charAt(i);
new_s[j++] = '#';
}
// new_s[j] = '\0';
return j;
}
}
C++版:
#include <cstdio>
#include <iostream>
#include <vector>
#include <cmath>
#include <map>
#include <set>
#include <cstring>
using namespace std;
const int maxn = 110000 + 10000;
char s[maxn], new_s[maxn*2];
int p[maxn*2];
int init() {
memset(p, 0, sizeof(p));
int len = strlen(s);
new_s[0] = '$';
new_s[1] = '#';
int j = 2;
for (int i = 0; i < len; i++) {
new_s[j++] = s[i];
new_s[j++] = '#';
}
new_s[j] = '\0';
return j;
}
int max(int a, int b) {
if (a > b) return a;
else return b;
}
int min(int a, int b) {
if (a < b) return a;
else return b;
}
int main() {
while (~scanf("%s", s)) {
int len = init();
int max_len = 0;
int id = 0;
int mx = 0;
for (int i = 1; i < len; i++) {
if (i < mx) {
p[i] = min(p[2*id - i], mx - i);
}
else {
p[i] = 1;
}
while (new_s[i - p[i]] == new_s[i + p[i]]) { p[i]++; }
if (mx < p[i] + i) { id = i; mx = i + p[i]; }
max_len = max(max_len, p[i] - 1);
}
printf("%d\n", max_len);
}
return 0;
}