leetcode打卡系列-1

leetcode打卡系列-1

无重复字符的最长子串

这道题是leetcode的第三题,也是比较经典的一道。题目说让找到任意一个字符串的无重复字符的子串。如’abcabcbb’的无重复字符的最长子串是’abc’,所以输出长为3。

解题的常规思路有以下两种:

一 暴力枚举
对给定字符串进行枚举,找到原始字符串的所有子字符串(两层for循环即可)。接着对所有的字符串进行判断,看是否无重复字符,然后求出满足条件的最长子串长度。第一种方法时间复杂度很高,大家可以练练手。

二 滑动窗口法

  • 假设我们现在有一个滑动窗口从左向右沿着字符串滑动,用指针left和指针i来表示窗口的下标。用res来表示无重复字符的最长子串的长度。用一个哈希表m来统计,随着滑动窗口的向右移动,所有字符最后出现位置的下标值。举个例子,对于字符串‘abcdeabc’,假设滑动窗口现在为’abcde’,则left=0,i=4,res=5,hash表m为{a:0,b:1,c:2,d:3,e:4}。但是当窗口继续右移的时候,我们就要更新a的值变为5,以此类推。

  • 我们希望滑动窗口中的字符均是不重复的。这样的话,当滑动窗口每向右移动一个字符时,只需要判断新字符是否在此前所有的字符中出现过。如果没有出现过,即哈希表中没有记录该字符之前出现的位置,则当前的最长子串长是i-left+1与原res中大的那一个,即原滑动窗口长加新出现的字符长。

  • 如果新字符在此前的所有字符中出现过,即哈希表中记录着该字符之前出现的位置,则有两种可能。第一,在滑动窗口外部出现,这时最长子串长依然是i-left+1与原res中大的那一个。第二,在滑动窗口内部出现,这时应该将left指针设定为在滑动窗口内出现的重复字符的位置。最后,在每次移动滑动窗口时应该更新hash表m中值。

def func(s):
    left,res = 0,0
    m = {}
    for i in range(len(s)):
        if s[i] not in m:
            res = max(res,i-left+1)
        else:
            if m[s[i]] >= left:
                left = m[s[i]]
            else:
                res = max(res,i-left+1)
        m[s[i]] = i + 1
    return res

你可能感兴趣的:(leetcode)