LeetCode 題3 無重複字元的最長子串
阿新 • • 發佈:2018-12-09
刷LeetCode時遇到的一道覺得稍微有點難度的題,記錄一下
給定一個字串,找出不含有重複字元的最長子串的長度。
示例 1:
輸入: "abcabcbb"
輸出: 3
解釋: 無重複字元的最長子串是 "abc",其
長度為 3。
示例 2:
輸入: "bbbbb"
輸出: 1
解釋: 無重複字元的最長子串是 "b"
,其長度為 1。
示例 3:
輸入: "pwwkew" 輸出: 3 解釋: 無重複字元的最長子串是"wke"
,其長度為 3。 請注意,答案必須是一個子串,"pwke"
是一個子序列 而不是子串。
本題的主要思路如下:
最簡單的思路肯定是先從頭開始遍歷,迴圈到第N個字元,在第N個字元之前的字串中遍歷,看是否存在N,若不存在,則N+1繼續,若存在,記住目前的子串長度,從下一個字元開始繼續遍歷。這種最壞的情況下是要遍歷(n+1)*n/2 次。
轉換思路,在遍歷的過程中,可以把之前的字串中存在的字元存在一個Map中,這樣確認下一個字元是否在之前的串中就只需要在Map中查詢,Map的key為字元,value為該字元在全字串中的索引。
定義幾個變數,其中iPosition是用來記錄目前的子串是從哪裡開始。比如abcaef,iPosition一開始為0,當遍歷到i ==3時,a出現了重複,這時候iPosition應該加1變為1。
如abcbef,iPosition一開始為0,當遍歷到i ==3時,abcb出現了重複,可以發現iPosition加1的話,從b開始遍歷,到了bcb又出現了重複,且子串的長度還小於abcb。可以發現iPosition的正確位置應變為重複的字元所在map中的vaule+1(這也是為什麼Map中存的value為索引的原因)。
在while迴圈中開始遍歷字串,若字串中的字元不在Map中,說明目前沒有重複,i++,且該字元加入Map中。若出現重複,先計運算元串長度,然後把老iPosition到新iPosition之間的字元,從Map中刪除(因為要從新iPostion之後開始計算了)。最後把Map中字元對應的value替換成最新的。
while迴圈的結束條件:
1.字串中剩下的子串長度已經小於目前的result
2.字串結束。
迴圈中的if判斷若為真是不會重新整理Result的,所以迴圈結束後要重新整理一次。比較一下目前的Result和最後得到的子長度,取大者即為結果。
class Solution { public: int lengthOfLongestSubstring(string s) { map<char,int> mcharint; int result = 0; int iPosition = 0; int i = 0; int size = s.size(); while(size-iPosition > result && s[i] !=NULL) { auto iter = mcharint.find(s[i]); //Not find it if(iter == mcharint.end()) { mcharint[s[i]] = i; } //Find it else { result = (i - iPosition)>result?(i - iPosition):result; for(int j = iPosition;j<iter->second + 1;j++) { mcharint.erase(s[j]); } iPosition = iter->second + 1; mcharint[s[i]] = i; } i++; } result = (i-iPosition)>result?(i-iPosition):result; return result; } };