卧槽,原“滑”~
最近刷了一个月的滑动窗口算法,收获颇丰,不禁感慨:卧槽,原来可以这样"滑"(开头点题)
下面是刷题滑动窗口的一些经验分享。
首先,答案有关子数组,子串的题目,优先考虑滑动窗口。将滑动窗口的题分为三个大类:定长滑动窗口,不定长滑动窗口
定长滑动窗口
这类题应该是最简单的,按以下模板,一招鲜,吃遍天。
- 1.
初始化将滑动窗口压满,取得第一个滑动窗口的目标值
- 2.
继续滑动窗口,每往前滑动一次,需要同时删除一个和添加一个元素
不定长滑动窗口
即可变窗口大小 对于可变窗口,我们同样固定初始化左右指针 l 和 r,分别表示的窗口的左右顶点。后面有所不同,我们需要保证:
-
l 和 r 都初始化为 0
-
r 指针移动一步
-
判断窗口内的连续元素是否满足题目限定的条件
-
如果满足,再判断是否需要更新最优解,如果需要则更新最优解。并尝试通过移动 l 指针缩小窗口大小。
-
如果不满足,则继续。
-
-
形象地来看的话,就是 r 指针不停向右移动,l 指针仅仅在窗口满足条件之后才会移动,起到窗口收缩的效果。
不定长滑动窗口题型详细可分为三类:1.求最长/最大 2.求最短/最小 3.求子数组个数
一般要用到①双指针:左指针start 右指针end②哈希表(数组):记录元素的个数或者索引
特别的
求最长/最大,一般返回的res初值为0,求最短/最小一般返回的res初值为length+1,这个length视操作的数组或字符串的长度而定。
难点在于根据题目要求,左指针要怎么动?什么时候动,动到什么位置?这些问题都视题目而定,没有固定套路,比较灵活,需要多积累经验,反复刷。
例如,要求窗口内的元素不重复:则需要额外记录窗口内重复元素的个数,start++到重复元素个数变为0为止(有时候在满足题目要求时,可以直接将start移到重复元素的索引最大值位置);要求窗口内元素的和要满足什么条件,则start++直到满足条件为止;要求记录滑动窗口内的最小值和最大值,则需要双端队列,此时不需要双指针
求子数组个数,这类题再分成两类:
1.子数组需要满足的要求是,元素个数小于某个数k。这类题滑动窗口满足要求时,那它右边界固定的子数组(0~start-1,end)都满足要求,即结果res+=start。
2.子数组需要满足的要求是,元素求和或者求乘积要小于某个数k。这类题的结果则是滑动窗口内部右边界固定的子数组(start~end,end)都满足要求,即结果res+=end-start+1。
多指针滑动窗口
这类题的很灵活,暂时没想到固定的模板。
一般思路是这样的:这类题一般最容易想到的是暴力解法,但会超时。
所以可以考虑是否具有单调性。何为单调性?单调性:假设i~j包含了子串T,那么当i++,j也一定是增加的,这就是单调性。
结语
暂时就想到这些,一些题目还会将滑动窗口,前缀和,哈希表,双端队列等混合在一起考察,以后刷多了再总结。
滑动窗口还是得多画画图来理解,虽然我已经尽力地想描述清楚,但文字终究感觉还是有些苍白晦涩。
(小声bb:第一次在星球发文章,这排版怎么这么怪咧)
