刷题小记三:滑动窗口

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

无重复字符的最长子串

思路

一次遍历

借助HashSet,加入右指针遍历过的元素, 检查重复。

无重复 -> 加入set -> 右指针继续移动

有重复 -> 左指针指向的元素出set -> 左指针缩短左边界 -> 加入set -> 右指针继续移动

最长字串长度:right - left + 1

239. 滑动窗口最大值 hard

滑动窗口最大值

思路

1. 使用 双端队列 表示 滑动窗口,并且是单调队列
头:删除过期元素,位置 i-k
尾:维护单调递减,加入新元素
此时队列第一个元素就是最大值
2. 单调队列存储的是 数组下标

Deque(双端队列)是 Java 中的一种数据结构,允许从两端插入和删除元素。

常用方法

  1. 添加元素

    • void addFirst(E e):在双端队列的头部插入元素。
    • void addLast(E e):在双端队列的尾部插入元素。
    • boolean offerFirst(E e):在头部插入元素,如果成功返回 true,否则返回 false
    • boolean offerLast(E e):在尾部插入元素,如果成功返回 true,否则返回 false
  2. 移除元素

    • E removeFirst():移除并返回头部的元素。如果队列为空则抛出异常。
    • E removeLast():移除并返回尾部的元素。如果队列为空则抛出异常。
    • E pollFirst():移除并返回头部的元素,如果队列为空则返回 null
    • E pollLast():移除并返回尾部的元素,如果队列为空则返回 null
  3. 查看元素

    • E getFirst():返回头部的元素但不移除,如果队列为空则抛出异常。
    • E getLast():返回尾部的元素但不移除,如果队列为空则抛出异常。
    • E peekFirst():返回头部的元素但不移除,如果队列为空则返回 null
    • E peekLast():返回尾部的元素但不移除,如果队列为空则返回 null
  4. 其他方法

    • int size():返回双端队列中的元素数量。
    • boolean isEmpty():检查双端队列是否为空。
    • void clear():移除双端队列中的所有元素。

 窗口右边队头,左边队尾

76.最小覆盖字串

最小覆盖子串

思路

滑动窗口

这道题要求我们返回字符串 s中包含字符串 t 的全部字符的最小窗口,我们利用滑动窗口的思想解决这个问题。

因此我们需要两个哈希表

hs哈希表维护的是s字符串中滑动窗口中各个字符出现多少次

ht哈希表维护的是t字符串各个字符出现多少次。

如果hs哈希表中包含ht哈希表中的所有字符,并且对应的个数都不小于ht哈希表中各个字符的个数,那么说明当前的窗口是可行的,可行中的长度最短的滑动窗口就是答案。

过程如下:

1、遍历t字符串,用ht哈希表记录t字符串各个字符出现的次数。

2、定义两个指针 left 和 right,left 指针用于收缩窗口,right指针用于延伸窗口,则区间[left,right]表示当前滑动窗口。首先让i和j指针都指向字符串s开头,然后枚举整个字符串s ,枚举过程中,不断增加i使滑动窗口增大,相当于向右扩展滑动窗口。

3、每次向右扩展滑动窗口一步,将s[right]加入滑动窗口中

4、对于新加入的字符s[i],如果hs[s[right]] <= ht[s[right]],说明当前新加入的字符s[i]是必需的,且还未到达字符串t所要求的数量。

需要事先定义一个cnt变量, cnt维护的是s字符串[left,right]区间中满足t字符串的元素的个数,记录相对应字符的总数。新加入的字符s[right]必需,则cnt++。

5、扩展滑动窗口的同时也收缩滑动窗口。如果左边界的值不在ht表中 或者 它在hs表中的出现次数多于ht表中的出现次数,此时我们就需要向右收缩滑动窗口,j++并使hs[s[left]]--

6、当cnt == t.size时,说明此时滑动窗口包含符串 t 的全部字符。我们重复上述过程找到最小窗口即为答案。

时间复杂度分析: 两个指针都严格递增,最多移动 n 次,所以总时间复杂度是 O(n)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值