1. 程式人生 > >求最長迴文子串_Manacher演算法_Java實現

求最長迴文子串_Manacher演算法_Java實現

通過對大神C程式碼的分析學習,結合自身理解,留下自己的Java實現過程。

原文: http://blog.csdn.net/xingyeyongheng/article/details/9310555

Manacher演算法求最長迴文子串,其時間複雜度幾乎是o(n),利用迴文的特性,儘可能的使用已計算過的資料,避免大量重複計算。

原文程式碼是C的,此處貼出java程式碼,原文講解非常詳細,想深入理解的朋友移步原文,

/*
 * 求最長迴文子串
 * */
public class 最長迴文子串 {
	static int[] p;//陣列長度和封裝串相同,代表在封裝串中以當前字元為中心的迴文串長度。
	public static void main(String[] args) {
		
		String str = "ggabaabaabaaball";//原串
		String s = "$#";//進行串封裝,便於統一串長度的奇偶性
		for (int i = 0; i < str.length(); i++)
			s += str.charAt(i) + "#";

		int max = 0;//記錄P陣列的最大值。PS:p[i]-1就是原串中    當前位置字母為中心的迴文串大小 
		int id = 0;//當前查詢位置之前,最大回文串的中心的下標
		p = new int[s.length()];

		for (int i = 0; i < s.length(); i++) {//遍歷封裝串

			int maxLen = p[id] + id;//當前查詢位置之前,已知能影響最右邊的串
			
			if (maxLen > i)//當前遍歷元素在之前最大回文串的影響範圍之內
				p[i] = Math.min(p[2 * id - i], maxLen - i);

			while (i + p[i] < s.length() && i - p[i] >= 0//當前遍歷元素在最低長度之上,兩邊擴張對比
					&& s.charAt(i - p[i]) == s.charAt(i + p[i]))
				++p[i];

			if (maxLen < i + p[i])//更新已知最大串資訊
				id = i;

			if (max < p[i])//保留最大值資訊
				max = p[i];
		}
		System.out.println(max - 1);
	}
}