題目
給定一個字串 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;