无重复字符的最长子串——滑动窗口法?

Posted 微笑小狗

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了无重复字符的最长子串——滑动窗口法?相关的知识,希望对你有一定的参考价值。

给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。

示例 1:

输入: "abcabcbb"
输出: 3 
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。

示例 2:

输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。

示例 3:

输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
     请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。

我的方法(滑动窗口法?)
class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        s_save=[]
        res = 0
        count=0
        for i in range(len(s)):
            if s[i] not in s_save:
                s_save.append(s[i])
                count+=1
            else:
                s_save.append(s[i])
                index = s_save.index(s[i])+1
                s_save = s_save[index:]
                count = len(s_save)
            res = max(count,res)
        return res

  别人的方法

class Solution:
    def lengthOfLongestSubstring(self, s):
        """
        :type s: str
        :rtype: int
        """
        st = {}
        i, ans = 0, 0
        for j in range(len(s)):
            if s[j] in st:
                i = max(st[s[j]], i)
            ans = max(ans, j - i + 1)
            st[s[j]] = j + 1
        return ans;

解释:

i是截至j,以j为最后一个元素的最长不重复子串的起始位置,即索引范围是[i,j]的子串是以索引j为最后一个元素的最长子串。 当索引从j-1增加到j时,原来的子串[i,j-1]新增了一个元素变为[i,j],需要判断j是否与[i,j-1]中元素有重复。所以if s[j] in st:是判断s[j]相同元素上次出现的位置,和i孰大孰小。如果i大,说明[i,j-1]中没有与s[j]相同的元素,起始位置仍取i;如果i小,则在[i,j-1]中有了与s[j]相同的元素,所以起始位置变为st[s[j]]+1,即[st[sj]+1,j]。而省略掉的else部分,由于s[j]是第一次出现所以前面必然没有重复的,仍然用i作为起始位置即可。 后面的ans=max(ans,j-i+1)中,括号中前者ans是前j-1个元素最长子串长度,j-i+1是以s[j]结尾的最长子串长度,两者(最长子串要么不包括j,要么包括j)取最大即可更新ans,遍历所有i后得到整个输入的最长子串长度。 

 

以上是关于无重复字符的最长子串——滑动窗口法?的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode T3.Longest Substring Without Repeating Characters/无重复最长子串

滑动窗口:无重复字符的最长子串

3. [数组][滑动窗口]无重复字符的最长子串

滑动窗口-3. 无重复字符的最长子串

力扣.求无重复字符的最长子串 C++ 滑动窗口

滑动窗口6:LeetCode3.无重复字符的最长子串