每日leetcode——3. 無重複字元的最長子串

Ethan發表於2022-03-06

題目

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

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

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

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

暴力列舉

思路一:以每個字元為開始,遍歷字串,用一個字典儲存遍歷的字元,遇到重複的就結束,用一個陣列儲存本次無重複子串的長度,返回最大的

def lengthOfLongestSubstring(s):
    if not s:
        return 0
    
    slen = [1] * len(s)
    for i in range(0,len(s)):
        hashTable = {}
        hashTable[s[i]]=1
        for j in range(i+1, len(s)):
            if s[j] in hashTable:
                break
            else:
                hashTable[s[j]]=1
                slen[i]+=1
    return max(slen)

滑動視窗

# 思路二:滑動視窗
# 定義兩個指標,i和j,i作為無重複子串的開頭,j作為無重複子串的結尾
# 定義一個字典st,用來儲存每個字元的最後一次出現的位置
# 定義一個ans變數,用來儲存最長無重複子串的長度

# 初始時,i,j=0,都在開頭位置
# 隨著for迴圈遍歷字元,j不斷向後移動
# 在j移動的過程中,如果當前字元在st中已經存在了,說明之前的字元中存在相同的字元

# 但是當前視窗中的子字串是否有重複,需要分情況判斷:

# 如果重複字元在視窗內,即i的位置<=重複字元的最新位置(..[i..重複字元..j]..)
# 則當前子串結束,需要移動i滑動視窗,將i移動到重複字元的下一個位置(..重複字元[i..j]..)

# 如果重複字元在視窗前,即重複字元的最新位置<i的位置 (..重複字元..[i..j]..),
# 說明當前視窗的子串是無重複的,則i保持不動,

# i和j的位置都確定好後,再更新ans,ans=Max(ans, j-i+1),當前的長度和之前的長度比較,選最大的,讓ans儲存的是最大長度
# 最後將{當前字元:出現的位值}儲存在字典st中

def lengthOfLongestSubstring(s):
    st = {}
    i, ans = 0, 0
    for j in range(len(s)):
        if s[j] in st:
            i = max(i, st[s[j]]+1)
        ans = max(ans,j-i+1)
        st[s[j]] = j
    return ans;

相關文章