package com.zcj.alogrithm;
public class Manacher {
public static void main(String[] args){
String s="adsfddsfdddddff";
int maxLength=computeMaxPString(s);
System.out.println(maxLength);
}
private static int computeMaxPString(String s) {
StringBuilder ss= new StringBuilder();
ss.append("#");
for(int i=0;i<s.length();i++){
ss.append(s.charAt(i));
ss.append("#");
}
String string= new String(ss);
return getLen(string);
}
private static int getLen(String ss) {
// p[i]表示以i为中心的回文的最大半径,i至少为1,即该字符本身
int [] p = new int[ss.length()];
// mx表示已知的回文中,最右的边界的坐标
int mx = -1;
// id表示已知的回文中,拥有最右边界的回文的中点坐标
int id = -1;
// 2.计算所有的p
// 这个算法是O(n)的,因为mx只会随着里层while的迭代而增长,不会减少。
for (int i = 0; i < ss.length(); i ++) {
// 2.1.确定一个最小的半径
int r = 1;
if (i <= mx) {
r = Math.min(p[id] - i+id, p[2 * id - i]);
}
// 2.2.尝试更大的半径
while (i - r >= 0 && i + r < ss.length() && ss.charAt(i - r) == ss.charAt(i + r)) {
r++;
}
// 2.3.更新边界和回文中心坐标
if (i + r - 1> mx) {
mx = i + r - 1;
id = i;
}
p[i] = r;
}
// 3.扫描一遍p数组,找出最大的半径
int maxLength = 0;
for (int r : p) {
if (r > maxLength) {
maxLength = r;
}
}
return maxLength - 1;
}
}
Manacher算法实现求最长回文子串的长度
最新推荐文章于 2025-05-28 00:56:57 发布