LeetCode——無重複字元的最長子串

baijimao發表於2019-04-27

題目內容

給定一個字串,請你找出其中不含有重複字元的 最長子串 的長度。 示例 1:

輸入: "abcabcbb"
輸出: 3
解釋: 因為無重複字元的最長子串是 "abc",所以其長度為 3。
複製程式碼

示例2:

輸入: "bbbbb"
輸出: 1
解釋: 因為無重複字元的最長子串是 "b",所以其長度為 1。
複製程式碼

示例3:

輸入: "pwwkew"
輸出: 3
解釋: 因為無重複字元的最長子串是 "wke",所以其長度為 3。
     請注意,你的答案必須是 子串 的長度,"pwke" 是一個子序列,不是子串。
複製程式碼

解題思路

這裡講述的我自己的解題思路的確是笨的要死,不過也是我自己通過對問題的本質分析總結出來的,暫且記錄一下,在有了自己的解題思路後去學習別人更加優秀的解題思想,對於我的提升還是蠻大的。

請看圖:

LeetCode——無重複字元的最長子串
首先對圖中的變數做一下介紹:

char curchar; // 記錄當前讀取到的字元
String curMaxStr; // 記錄最近最長無重複字串
int curMaxLen; // 記錄最近最長無重複字串的長度
String totalMaxStr; // 記錄總體最長無重複字串
int totalMaxLen; // 記錄總體最長無重複字串的長度
複製程式碼

接下來是我對問題的思考:

  1. 對字串進行for迴圈遍歷,使用curChar記錄當前讀取到的字元;
  2. 判斷curMaxStr中有沒有這個字元curChar,如果沒有,就將這個字元拼接到curMaxStr,並且將curMaxLen加1,如果curMaxLen大於等於totalMaxLen,就將curMaxStrcurMaxLen賦值給totalMaxStrtotalMaxLen
  3. 如果curMaxStr有這個字元curChar,那麼從當前位置向前反序遍歷,必然能找到與之重複的那個字元的位置,將重複的字元之後到當前curChar位置的字串賦值給curMaxStr,如果curMaxLen大於等於totalMaxLen,就將curMaxStrcurMaxLen賦值給totalMaxStrtotalMaxLen

具體程式碼

public static int lengthOfLongestSubstring(String s) {
        // 當字串s的長度為0時,那麼就沒有最長子串了
        char curChar;
        String curMaxStr = "", totalMaxStr = "";
        int curMaxLen = 0, totalMaxLen = 0;
		if(s.length() == 0) {
            totalMaxLen = 0;
        }
        for(int i = 0; i < s.length(); i++) {
            curChar = s.charAt(i);
            // 當前字元與當前最長字串中的字元沒有重複時
            if (!curMaxStr.contains(String.valueOf(curChar))) {
            	// 將當前字元拼接到當前最長字串上
				curMaxStr += curChar;
				// 當前最長長度+1
				curMaxLen ++;
				if (curMaxLen >= totalMaxLen) {
					totalMaxStr = curMaxStr;
					totalMaxLen = curMaxLen;
				}
				//System.out.println("++++curChar:" + curChar + " curMaxStr:" + curMaxStr + " curMaxLen:" + curMaxLen + " totalMaxStr:" + totalMaxStr + " totalMaxLen:" + totalMaxLen);
			}
            else {
            	// 記錄重複點的位置
				int repeatPos = i;
				curMaxStr = String.valueOf(curChar);
				curMaxLen = 1;
				// i沒有遍歷到開始處,並且從重複位置向前移動的這個字元與重複字元不重複
				while(i > 0 && s.charAt(i - 1) != curChar) {
					curMaxStr = s.charAt(--i) + curMaxStr;
					curMaxLen++;
					//System.out.println("----curChar:" + curChar + " curMaxStr:" + curMaxStr + " curMaxLen:" + curMaxLen + " totalMaxStr:" + totalMaxStr + " totalMaxLen:" + totalMaxLen);
					if (curMaxLen >= totalMaxLen) {
						totalMaxStr = curMaxStr;
						totalMaxLen = curMaxLen;
					}
				}
				i = repeatPos;
			}
        }
        return totalMaxLen;
    }
複製程式碼

下面是我在結了這個問題之後,在評論區看到的別人的解法,感覺特別棒,在這裡也分享處理,如果讀者覺得我的想法太笨,可以看看這段程式碼:

public static int lengthOfLongestSubstring(String s) {
        int maxLength = 0;
        String str = "";
        for (int i = 0; i < s.length(); i++) {
			int index = str.indexOf(s.charAt(i));
			str = str + s.charAt(i);
			//出現重複
			if(index >= 0) {
				str = str.substring(index + 1);
			} else {
				if (str.length() > maxLength) {
					maxLength = str.length();
				}
			}
		}

        return maxLength;

    }
複製程式碼

相關文章