1. 程式人生 > >LeetCode 3. Longest Substring Without Repeating Characters 題解——Java

LeetCode 3. Longest Substring Without Repeating Characters 題解——Java

題目要求:給定一個字串,找出字串中沒有重複字元的子串的最大長度。

思路:對於字串中的每一個字元,找出以每一個字元為最後元素的,符合條件的子串的長度,將各個子串的長度值儲存起來。遍歷各個子串的長度值,其中的最大值即為該字串的符合條件的最長子串的長度。

舉例來說,對於字串“pwwkew”,

以第一個字元p為結尾的符號條件的最長子串為"p",因此記錄下該子串的長度為       1;

以第二個字元w為結尾的符合條件的最長子串為“pw”,因此記錄下該子串的長度為       2;

以第三個字元w為結尾的符合條件的最長子串為“w”,因此記錄下該子串的長度為         1;

以第四個字元k為結尾的符合條件的最長子串為“wk”,因此記錄下該子串的長度為        2;

以第五個字元w為結尾的符合條件的最長子串為“wke”,因此記錄下該子串的長度為     3;

以第六個字元w為結尾的符合條件的最長子串為“kew”,因此記錄下該子串的長度為      3;

遍歷右側儲存的各個子串的長度值[1,2,1,2,3,3],得到該字串的符合條件的最長子串的長度為3(子串“wke” 或 子串“kew”)

思路明確之後,本題的另外一個難點是,如果找到以字串中某個字元(記為c)為結尾的最長子串。我的方法是:使用佇列儲存位於字元c之前的子串,該子串中無重複元素。在計算以c字元結尾的最長子串時,首先判斷佇列中是否有c字元,有的話就將佇列中的c及其之前的字元全部出佇列,然後將新的c入佇列,這樣就得到了以這個新的c為結尾的最長子串;如果佇列中沒有c字元,那麼直接把c入佇列,此時新的佇列中仍然沒有重複元素,符合條件,此時佇列中的儲存的子串就是以c為結尾的最長子串。

Java程式碼如下:

public class Solution {
    public int lengthOfLongestSubstring(String s) {
    	if(s.length() == 0){
    		return 0;
    	}
    	int length = s.length();
    	int[] count = new int[length];
    	// 對於每一個下標i,那一時刻佇列中儲存的是以nums[i]為最後一個元素的不重複子串的長度值
    	Queue<Character> queue = new LinkedList<Character>();
    	for(int i=0; i<s.length(); i++){
    		// 當前處理的字元
    		char current = s.charAt(i);
    		// 如果佇列中有和當前字元相同的字元
    		if(queue.contains(current)){
    			// 則將佇列中與當前字元相同的字元及之前的字元全部出佇列
    			while(queue.remove()!= current){
    			}
    			// 當前字元進佇列
    			queue.add(current);
    			count[i] = queue.size();
    		} else {
    		    // 如果佇列中沒有和當前字元相同的字元
    			queue.add(current);
    			count[i] = queue.size();
    		}
    	}
    	int max = count[0];
    	// 遍歷count陣列,其中最大的子串長度值就是整個字串的符合條件的最大子串長度值
    	for(int num: count){
    		if(num > max){
    			max = num;
    		}
    	}
    	return max;
    }
}