回文字符串123321
回文直径:6
回文半径:3
求一个字符串中的最长回文字符串. abc123321def
一般会在原字符串中添加特殊字符,比如添加"#".
变成#a#b#c#1#2#3#3#2#1#d#e#f#
public class Code_Manacher {
public static void main(String[] args) {
System.out.println(manacher("a"));
}
// 求回文串的长度
public static int manacher(String s){
if(null == s || s.length() == 0){
return 0;
}
// "abcde" -> "#a#b#c#d#e#"
char[] str = manacherString(s);
// 回文半径的大小
int[] pArr = new int[str.length];
int C = -1;
int R = -1; // 最右的扩成功位置,再下一个位置
int max = Integer.MIN_VALUE;
int end = 0;
for (int i = 0; i < str.length; i++) {
pArr[i] = R > i ? Math.min(pArr[2*C-i],R-i) :1;
while(i+pArr[i]<str.length && i-pArr[i]>-1)
{
// 向两边扩展
if(str[i+pArr[i]] == str[i-pArr[i]]){
pArr[i]++;
}else{
break;
}
}
// R被扩展
if(i+pArr[i]>R){
R = i+pArr[i];
C = i;
}
//max = Math.max(max,pArr[i]);
if(max < pArr[i]){
max = pArr[i];
end = R/2-1; // 记录最长回文字符结束的位置
}
}
// for (int i = 0; i < str.length; i++) {
// System.out.printf("%c",str[i]);
// }
System.out.println(end);
for (int i = end+2-max; i <=end ; i++) {
System.out.printf("%c",s.charAt(i)); // 打印出回文字符串
}
System.out.println();
return max-1; // 减去回文串中的最后一个#
}
public static char[] manacherString(String s){
char[] str = new char[2*s.length()+1];
str[0]='#';
int j = 1;
for (int i = 0; i < s.length(); i++) {
str[j++] = s.charAt(i);
str[j++] = '#';
}
return str;
}
}