O(n)時間複雜度求最長迴文串

該算法思想轉載自:http://zhuhongcheng.wordpress.com/2009/08/02/a-simple-linear-time-algorithm-for-finding-longest-palindrome-sub-string/

1、問題描述

對於給定的一的個字符串,求出它的最長迴文串長度。(迴文串的定義在這裏就不綴述了)

2、解決思路

先將特殊字符'#'插入字符串中,例如原字符串str="abaaca",得插入'#'後的字符串爲:newStr="#a#b#a#a#c#a#",這種方式方法的好處將奇數長度迴文串與偶數長度迴文串統一起來考慮了,然後用一個輔助數組P記錄以每個字符爲中心的最長迴文串的信息。P[id]記錄的是以字符newStr[id]爲中心的最長迴文串,當以str[id]爲第一個字符,這個最長迴文串向右延伸了P[id]個字符,P[id]-1就是該回文子串在原串中的長度。

3、與算法相關的圖片(好好理解理解)


4、JAVA代碼

public class LongestPalindromeString {
	private String str="";  //保存帶'#'字符串
	public LongestPalindromeString(String str) {
		super();
		this.str = splitStr(str);
	}
	
	private String splitStr(String str){  //將原串轉換成帶'#'的字符串
		 StringBuffer buffer=new StringBuffer();
		 buffer.append("$"); //將str[0]設爲'$',使字符串從索引1開始
		 for(int i=0;i<str.length();i++){
			 buffer.append("#");
			 buffer.append(str.charAt(i));
		 }
		 buffer.append("#");
		 return buffer.toString();
	}
	public int[] getPalindrome(){
		int max=0,id=1;
		int[] p=new int[str.length()]; //p[id]用於保存每個str[id]爲中心的最長迴文串
		for(int i=1;i<str.length();i++){
			if(max>i){
				p[i]=min(p[2*id-i],max-i); //P[2*id-i]代表上述圖片中出現的第一種情況,即上半個圖的情況
			}else{   //max-i表示上述圖片中出現的第二種情況,即下半個圖的情況
				p[i]=1;
			}
			while(i+p[i]<str.length()&&str.charAt(i-p[i])==str.charAt(i+p[i])){
				p[i]++;
			}
				
			if(i+p[i]>max){
				max=i+p[i];
				id=i;
			}
		}
		return p;
	}

	private int min(int i, int j) {
		// TODO Auto-generated method stub
		return i<j?i:j;
	}

	public static void main(String[] args) {
		LongestPalindromeString lonPa=new LongestPalindromeString("adfffd");
		int[] result=lonPa.getPalindrome();
		for(int i=0;i<result.length;i++)
		System.out.print(result[i]);
	}

}


後記:

每天學習一點點

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章