所谓滑动窗口,就是不断的调节子序列的起始位置和终止位置,从而得出想要的结果,滑动窗口也可以理解为双指针法中快慢指针的一种。
LeetCode209.长度最小的子数组
窗口是满足其和 ≥ s 的长度最小的连续子数组
【外层for更改一个指针,内层用while连续更新另一个指针】
窗口的起始位置如何移动:如果当前窗口的值大于s,窗口就要向前移动(也即该缩小)。
窗口的结束位置如何移动:窗口的结束位置就是遍历数组的指针,也就是for循环里的索引。
滑动窗口的精妙之处在于根据当前子序列和大小的情况,不断调节子序列的起始位置,sum -= nums[start++],从而将O(n^2)暴力解法降为O(n)。
关键点在于:若是寻找最小窗口,则在满足条件的情况下,如果窗口能够缩小则更新信息
76.最小覆盖子串
【具体做法】:
需要创建一个unorder_map维护目标字符串的各字母出现次数;另外最好再创建一个unordered_map记录遍历过程中目标字符串各字母出现的次数,方便修改,而且不用在滑动窗口变化的时候对上一个map进行惨改;然后在遍历过程如果达到目标字符串次数就收缩窗口左边界,并记录窗口起点,当收缩的窗口不能完全覆盖目标字符串就扩展窗口右边界,至再次能完全覆盖;当右窗口到达终点,左边界收缩完成,将此时的起点用于分割字符串
LeetCode 643.[子数组的最大平均数]先定义一个变量max保存最大值(要注意初始化的max应该是第一个窗口所求得的值,而不是0,不能忽略数组内k个最大连续组序列的和是负数的情况),然后left和right保存窗口两端。只要right不到数组边界,滑动窗口每次一变就计算窗口内的元素之和,然后和max比较看看是否保存。
【1、定义需要维护的变量】
涉及去重,因此需要一个哈希表
【2、定义窗口的首尾端 (start, end), 然后滑动窗口】
如果当前窗口不合法时, 用一个 while 去不断移动窗口左指针, 从而剔除非法元素直到窗口再次合法,也即如果哈希表中存储了即将加入滑动窗口的元素,那么需要不断的把窗口左边的元素移除窗口
【图源 公众号:吴师兄学算法】