您的位置:首页 > 其它

Manacher算法实现求最长回文子串的长度

2016-09-02 14:52 344 查看
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;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: