3. 无重复字符的最长子串

给定一个字符串 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
posted @ 2021-07-14 22:41  青铜时代的猪  阅读(59)  评论(0)    收藏  举报