class Solution {
public String longestPalindrome(String str) {
//生成带#标签的字符串
StringBuilder newStr = new StringBuilder();
StringBuilder resultStr = new StringBuilder();
newStr.append('#');
for (int i = 0; i < str.length(); i ++) {
newStr.append(str.charAt(i));
newStr.append('#');
}
//表示每个char在回文中的位置
int [] rad = new int[newStr.length()];
// max表示已知的回文中,右边界
int max= -1;
// id表示已知的回文中的中点坐标
int id = -1;
// 2.计算所有的rad
// 这个算法是O(n)的,因为max只会随着里层while的迭代而增长,不会减少。
for (int i = 0; i < newStr.length(); i ++) {
// 2.1.确定一个最小的半径
int r = 1;
if (i <= max) {
r = Math.min(rad[id] - i + id, rad[2 * id - i]);
}
// 2.2.尝试更大的半径
while (i - r >= 0 && i + r < newStr.length() && newStr.charAt(i - r) == newStr.charAt(i + r)) {
r++;
}
// 2.3.更新边界和回文中心坐标
if (i + r - 1> max) {
max = i + r - 1;
id = i;
}
rad[i] = r;
}
// 3.扫描一遍rad数组,找出最大的半径
int maxLength = 0;
int index=0;
for (int i=0;i<rad.length;i++) {
if (rad[i] > maxLength) {
maxLength = rad[i];
index=i;
}
}
System.out.print("最大回文子串是:");
for(int j=index-maxLength+1;j<index+maxLength;j++)
{
if(newStr.charAt(j)!='#')
resultStr.append(newStr.charAt(j));
}
return resultStr.toString();
}
}