Longest Palindromic Substring最长回文子串-Manacher算法
Manacher算法主要就是用来寻找字符串中的回文子串。
假设目标字符串是abbaca, 在空隙插值#得到新字符串s#a#b#b#a#c#a#。
假设当前找到的一个回文串,中心坐标是c, 半径是range(包含自己), 最右边界坐标是r=c+range-1,
那么在s[c-range+1...c)和s(c...c+range-1] (s(c...r])中的点对称的。
设p[i]表示以i为中心的最长回文半径,比如p[c]=range。
当i在s(c...c+range-1] 范围内时,在s[c-range+1...c)中镜像坐标为mirror=c*2-i,
此时有两种情况
- mirror-p[mirror]+1 > c-range+1,这样说明以mirror为中心的最大回文子串,整个范围都在c之内,根据对称性,以i为中心的最大回文子串也在c范围内,故可以直接p[i]=p[mirror]。
- mirror-p[mirror]+1 < c-range+1,此时mirror的左边界超过了c的左边界,当利用c的对称性时,必须舍弃超过左边界的范围,此时p[i]=mirror-c的左边界=c的右边界-i作为初始值,之后再继续计算边界外并更新p[i],直到找到i的边界。
public String longestPalindrome(String s) {
StringBuilder sb = new StringBuilder(s.length() * 2 + 1);
int n = s.length() * 2 + 1;
for (int i = 0; i < s.length(); i++) {
sb.append('#');
sb.append(s.charAt(i));
}
char[] t = sb.append('#').toString().toCharArray();
int[] p = new int[n];
int c = 0;
int r = 0;
int maxIndex = 0;
int maxR = 1;
for (int i = 0; i < n; i++) {
int mirror = c * 2 - i;
if (i < r) {
p[i] = Math.min(p[mirror], r - i);
}
while (i - p[i] >= 0 && i + p[i] < n && t[i - p[i]] == t[i + p[i]]) {
p[i]++;
}
if (p[i] > maxR) {
maxR = p[i];
maxIndex = i;
}
}
sb.setLength(0);
for (int i = maxIndex - p[maxIndex] + 1; i < maxIndex + p[maxIndex] - 1; i++) {
if (t[i] != '#') {
sb.append(t[i]);
}
}
return sb.toString();
}
posted on 2025-11-19 21:31 Lv Jianwei 阅读(0) 评论(0) 收藏 举报
浙公网安备 33010602011771号