1. 程式人生 > >找出字串的最長不重複子串,輸出長度和子串

找出字串的最長不重複子串,輸出長度和子串

方法一:窮舉法,空間複雜度是O(1),時間複雜度是O(N^4)


<pre name="code" class="java">public class Max_substring {
 
	public int max_unique_substring(char[] str){
	int maxlen = 0;
	int begin = 0;
	int n = str.length;
	for(int i = 0; i < n; ++i){
		for(int j = i+1; j < n; ++j){
			int flag = 0;
			//判斷子串是否有重複字元
			for(int m = i; m < j; ++m){
				for(int k = m+1; k < j; ++k){
					if(str[m] == str[k]){
						flag = 1;
						break;
					}
				}
				if(1 == flag) break;				
			}
			if(0 == flag && j-i+1 > maxlen){
				maxlen = j-i+1;
				begin = i;
			}
		}
		
	}
	StringBuffer s = new StringBuffer();
	for(int g = 0; g < n; ++g){
		s.append(str[g]);
	}
	System.out.println(s.toString().substring(begin,begin+maxlen)+","+maxlen+","+ begin +","+(begin+maxlen));
	return maxlen;
	}
	
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
 
		Max_substring max = new Max_substring();
		char[] s = {'a','x','b','d','e','b','p','q','a','w','u','v','a'};
		max.max_unique_substring(s);
	}
 
}

方法二:貪心演算法,時間複雜度O(N)

0 1 2 3 4 5 6 7 8 9 10 11 12
a x b d e b p q a w u v a
j i i

通過一次遍歷字串陣列,利用雜湊表記錄已經遍歷過的字元;演算法過程中維護著一個不重複的子串以及他的長度,如果出現了重複的字元則更新不重複子串的起始點並更新最大不重複子串的長;如上圖 j 為子串的起點,i 為子串的終點;此時位置 5 處的 b 在 位置2處出現過,就需要更新 j 使其到達位置3處的 d ,此時子串就變為了deb 長度為3;按此邏輯推理下去就會找到最長不重複子串debpaawuv 長度為9.

public class Max_substring2 {
 
	public int max_substring(char[] str){
		
		int length = str.length;
		int begin = 0;    //記錄最長子串的起點  以便輸出最長串
		int end = 0;	//記錄最長子串的終點  以便輸出最長串
		int maxlen = 0;        //最長不重複字串長度
		int j = 0;			//記錄當前不重複字串的起點
		int i = 0;          //記錄當前不重複字串的終點
		int hs[] = new int[128];   //用陣列代替雜湊表map
		int k =0;
		
		/* 將模擬hashmap的陣列初始化*/
		while(k < 128){
			hs[k] = -1;
			k++;
		}
			
		//遍歷字元陣列
		while(i < length){     
			if(hs[str[i]-0] >= j){   //如果當前維護的不重複子串中出現了str[i]
				j = hs[str[i]-0]+1;  //更新j
			}else{ 					//如果當前維護的不重複子串沒有出現str[i]
				if(i-j+1 > maxlen){
					maxlen = i-j+1;   /*更新結果取較大者*/
					begin = j;		  /*  並記錄當前較大子串的起點*/
					end = i;		 /*  並記錄當前較大子串的終點*/
				}
			}
			hs[str[i]-0] = i;        //更新map(實際上是更新模擬map的陣列)
			i++;
			
		}
		//列印輸出最長串
		for(int m = begin; m <= end; ++m){
			System.out.print(str[m]);
		}
		
		return maxlen;
		
	}
	
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
 
		Max_substring2 mxs = new Max_substring2();
		char[] str = {'a','x','b','d','e','b','p','q','a','w','u','v','a'};
		int maxlen = mxs.max_substring(str);
		System.out.println(" 最大不重複子串的長度:  "+maxlen);
	}
 
}