马拉车算法 Manacher
具体分析:博客园 - BIT祝威
代码实现 - Manacher
class Solution {
public String longestPalindrome(String s) {
// 特殊情况排除
if (s == null || s.isEmpty()) {
return "";
}
String t = transform(s);
int[] p = new int[t.length()];
// 中心位置
int C = 0;
// 右边界
int R = 0;
// 回文串最大半径
int maxLen = 0;
// 最长回文串对应中心
int pos = 0;
for (int i = 0; i < t.length(); i++) {
// i关于C的对称点
int j = 2 * C - i;
// 分三种情况进行赋值
p[i] = R >= i ? Math.min(p[j], R - i) : 0;
// 回文半径可增加的情况
while (i + p[i] + 1 < t.length() && i - p[i] - 1 >= 0
&& t.charAt(i + p[i] + 1) == t.charAt(i - p[i] - 1)) {
p[i]++;
}
if (p[i] > maxLen) {
maxLen = p[i];
pos = i;
}
// 更新中心点和右边界
if (i + p[i] > R) {
C = i;
R = i + p[i];
}
}
int left = (pos - maxLen) / 2;
int right = (pos + maxLen - 1) / 2;
return s.substring(left, right + 1);
}
// 字符串转换
public String transform(String s) {
StringBuilder builder = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
builder.append('#').append(s.charAt(i));
}
builder.append('#');
return builder.toString();
}
}