Manacher算法模板
该示例是返回字符串s
中最长的回文字符串
public String longestPalindrome(String s) {
StringBuilder sb = new StringBuilder();
sb.append('#');
for (int i = 0; i < s.length(); i++) {
sb.append(s.charAt(i)).append('#');
}
int[] p = new int[sb.length()];
int maxLen = 0, start = 0;
for (int i = 0; i < sb.length(); i++) {
int aux = 1, len = 0;
while ((i - aux) >= 0 && (i + aux) < sb.length() && sb.charAt(i - aux) == sb.charAt(i + aux)) {
aux++;
len++;
}
p[i] = len;
if (maxLen < len) {
maxLen = len;
start = (i - maxLen) / 2;
}
}
return s.substring(start, start + maxLen);
}
1、对原始字符串s进行预处理 添加符号#
StringBuilder sb = new StringBuilder();
sb.append('#');
for (int i = 0; i < s.length(); i++) {
sb.append(s.charAt(i)).append('#');
}
2、构建长度为扩张后数组长度的辅助数组p,用以存储最长回文半径
辅助数组 p 记录了新字符串中以每个字符为中心的回文子串的信息。手动的计算方法是“中心扩散法”,此时记录以当前字符为中心,向左右两边同时扩散,记录能够扩散的最大步数。(不包含当前字符本身)
数组p中最大的数字即是字符串s
的最长回文字符串长度L
最长回文字符串的起始点是,p中最大数字处的索引处index
减去L
再除以2
,根据长度L
即可取得整个最大回文字符串。
int[] p = new int[sb.length()];
int maxLen = 0, start = 0;
for (int i = 0; i < sb.length(); i++) {
int aux = 1, len = 0;
while ((i - aux) >= 0 && (i + aux) < sb.length() && sb.charAt(i - aux) == sb.charAt(i + aux)) {
aux++;
len++;
}
p[i] = len;
if (maxLen < len) {
maxLen = len;
start = (i - maxLen) / 2;
}
}
return s.substring(start, start + maxLen);