找出字符串的最长不重复子串,输出长度和子串

方法一:穷举法,空间复杂度是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);
	}
 
}

猜你喜欢

转载自blog.csdn.net/weixin_42648580/article/details/82556809