1. 程式人生 > 其它 >父元素如何圍住浮動子元素

父元素如何圍住浮動子元素

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

示例1:

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

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

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

Brute Force

有一個判斷當前字串為不重複的函式boolean allUnique(String substring)

.
然後兩重迴圈求解,時間複雜度\(O(n^3)\)

sliding window

在暴力搜尋中,boolean allUnique(String substring) 對於字串是從頭開始搜尋的。如果使用set的結構,可以將複雜度降到\(O(n^2)\)

Sliding Window Optimized

暴力搜尋會產生很多不必要的操作,比如\(s_{i,j}​\)代表字串 \(i​\)\(j-1​\) 沒有重複字串。則我們只需要判斷第 \(j​\) 個是否含於 \(s_{i, j}​\) 即可。如果不包含,則 \(s_{i,j}​\) 變為 \(s_{i,j+1}​\) 。如果包含,則從包含的下標的下一位置開始(記錄對應的位置)。

如下圖所示:

下一座標起始點即為2

這樣就把時間複雜度降到了\(O(n)\)

  def lengthOfLongestSubstring(self, s):
    """
    :type s: str
    :rtype: int
    """
    used = {}
    max_length = start = 0
    for i, c in enumerate(s):
      if c in used and start <= used[c]:
        start = used[c] + 1
      else:   
        max_length = max(max_length, i - start + 1)
            
      used[c] = i
    
    return max_length