7.15 LeetCode刷题记录(滑动窗口 中等x1)

7.15 LeetCode刷题记录

1、无重复字符串的最长子串(滑动窗口)

题目

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

示例 1:

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

示例 2:

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

示例 3:

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

解答

class Solution(object):
    def lengthOfLongestSubstring(self, s):
        dic, res, i = {}, 0, -1   # i是左指针
        for j in range(len(s)):  # j是右指针
            if s[j] in dic:     # 若当前元素在之前出现过,更新左指针
                # 当之前出现的元素在左右指针中间,左指针更新为之前元素下标,若不在中间,左指针不变
                i = max(i, dic[s[j]]) 
            dic[s[j]] = j    # 将当前元素加入哈希表中
            res = max(res, j - i)   
        return res

滑动窗口详解

滑动窗口,顾名思义,就是有一个大小可变的窗口,左右两端方向一致的向前滑动(右端固定,左端滑动;左端固定,右端滑动)。

可以想象成队列,一端在push元素,另一端在pop元素,如下所示:

假设有数组[a b c d e f g h]
一个大小为3的滑动窗口在其上滑动,则有:
[a b c]
[b c d]
[c d e]
[d e f]
[e f g]
[f g h]

适用范围

  • 1、一般是字符串或者列表
  • 2、一般是要求最值(最大长度,最短长度等等)或者子序列

算法思想

  • 1、在序列中使用双指针中的左右指针技巧,初始化 left = right = 0,把索引闭区间 [left, right] 称为一个窗口。

  • 2、先不断地增加 right 指针扩大窗口 [left, right],直到窗口中的序列符合要求。

  • 3、此时,停止增加 right,转而不断增加 left 指针缩小窗口 [left, right],直到窗口中的序列不再符合要求。同时,每次增加 left前,都要更新一轮结果。

  • 4、重复第 2 和第 3 步,直到 right 到达序列的尽头。

思路其实很简单:第 2 步相当于在寻找一个可行解,然后第 3 步在优化这个可行解,最终找到最优解。左右指针轮流前进,窗口大小增增减减,窗口不断向右滑动。

算法总结

滑动窗口算法就是用以解决数组/字符串的子元素问题
滑动窗口算法可以将嵌套的for循环问题,转换为单循环问题,降低时间复杂度

posted @ 2022-07-15 17:34  tlott  阅读(23)  评论(0编辑  收藏  举报