題目內容
給定一個字串,請你找出其中不含有重複字元的 最長子串 的長度。 示例 1:
輸入: "abcabcbb"
輸出: 3
解釋: 因為無重複字元的最長子串是 "abc",所以其長度為 3。
複製程式碼
示例2:
輸入: "bbbbb"
輸出: 1
解釋: 因為無重複字元的最長子串是 "b",所以其長度為 1。
複製程式碼
示例3:
輸入: "pwwkew"
輸出: 3
解釋: 因為無重複字元的最長子串是 "wke",所以其長度為 3。
請注意,你的答案必須是 子串 的長度,"pwke" 是一個子序列,不是子串。
複製程式碼
解題思路
這裡講述的我自己的解題思路的確是笨的要死,不過也是我自己通過對問題的本質分析總結出來的,暫且記錄一下,在有了自己的解題思路後去學習別人更加優秀的解題思想,對於我的提升還是蠻大的。
請看圖:
首先對圖中的變數做一下介紹:char curchar; // 記錄當前讀取到的字元
String curMaxStr; // 記錄最近最長無重複字串
int curMaxLen; // 記錄最近最長無重複字串的長度
String totalMaxStr; // 記錄總體最長無重複字串
int totalMaxLen; // 記錄總體最長無重複字串的長度
複製程式碼
接下來是我對問題的思考:
- 對字串進行for迴圈遍歷,使用
curChar
記錄當前讀取到的字元; - 判斷
curMaxStr
中有沒有這個字元curChar
,如果沒有,就將這個字元拼接到curMaxStr
,並且將curMaxLen
加1,如果curMaxLen
大於等於totalMaxLen
,就將curMaxStr
和curMaxLen
賦值給totalMaxStr
和totalMaxLen
。 - 如果
curMaxStr
有這個字元curChar
,那麼從當前位置向前反序遍歷,必然能找到與之重複的那個字元的位置,將重複的字元之後到當前curChar
位置的字串賦值給curMaxStr
,如果curMaxLen
大於等於totalMaxLen
,就將curMaxStr
和curMaxLen
賦值給totalMaxStr
和totalMaxLen
。
具體程式碼
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;
}
複製程式碼