2021/02 LeetCode 滑动窗口方法总结

二月有春节假期,在假期期间LeetCode十分仁慈的都给的是简单难度的题目,同时很多题目都是用滑动窗口方法来求解的:

2021/02/02 每日一题 替换后的最长重复字符
2021/02/03 每日一题 滑动窗口中位数
2021/02/04 每日一题 子数组最大平均数 I
2021/02/09 每日一题 K 个不同整数的子数组
2021/02/10 每日一题 字符串的排列
2021/02/15 每日一题 最大连续1的个数 (2种方法)
2021/02/18 每日一题 K 连续位的最小翻转次数 (直接翻转+滑动窗口)
2021/02/19 每日一题 最大连续1的个数 III
2021/02/21 每日一题 绝对差不超过限制的最长连续子数组
2021/02/23 每日一题 爱生气的书店老板
2021/02/28 每日一题 单调数列

一个月总结一个方法吧,上个月是并查集,这个月是滑动窗口,总结下方便日后回顾和记忆

使用滑动窗口的场景

总结上面的题目可以发现滑动窗口主要用于字符串数组数据,当需要获取这些数组内部子串的情况,就会用到滑动窗口,来获取不同子串的解决问题。

同时滑动窗口能够简化for循环的使用,优化for循环的嵌套,降低时间复杂度。

滑动窗口的实现

滑动窗口的建立:所有题目滑动窗口都是通过两个指针来实现的leftright,两个指针分别对应的是窗口的左右边界,移动窗口也是在循环中不断增加leftright的值。
滑动窗口的边界:滑动窗口的right移动到原数组的左侧的时候,那么就是滑动窗口的边界,一般用while(right < length)这种条件来判断窗口的滑动边界,当right的数值和传入数组(字符串)长度相同的时候,就是已经到顶了,那么就要跳出循环。

滑动窗口的关键问题

通过上面两点已经知道:

  1. 求子串问题的时候用滑动窗口
  2. 滑动窗口用指针实现,并且右指针到达数组(字符串)末尾的时候停止循环

那么接下来就是几个滑动窗口最关键的问题,平时使用的时候总结出这几个问题,基本上做完了,以2021/02/03 每日一题 滑动窗口中位数这道题目为例

  while(right<nums.length) {
    if(right-left+1 < k) {
      window = windowSort(window,nums[right])
    } else if(right-left+1 === k) {
      window = windowSort(window,nums[right])
      res.push(find(window,k))
    } else {
      window =windowDelete(window,nums[left])
      left++
      window = windowSort(window,nums[right])
      res.push(find(window,k))
    }
    right++
  }

这里的windowSort()方法是传入数据,并且排序数组
windowDelete()方法是删除对应的数据
while(right<nums.length){}对应的是滑动窗口的边界问题

当窗口扩展的时候(即当前窗口小于等于设定大小),窗口内的数据需要如何操作?
right-left+1 < k时候,即当前窗口还没有达到设定值k的时候,是移入数据并且排序
right-left+1 === k的时候,即窗口第一次成立的时候,窗口大小正好等于K的时候,是移入数据,并且第一次获取中位数
计算窗口大小用right - left + 1,因为数组是从0开始计数的,并且当right=0,left=0的时候窗口大小为1
什么时候指针left要右移(窗口缩小)?
right-left+1 === k的时候,进行移入数据和取中位数的操作,之后right++,窗口继续扩展了,那么right-left+1 > k窗口的大小就大于设定的值了,通过left++来实现窗口右移
当窗口缩小的时候,窗口内的数据需要如何操作?
窗口left右移(窗口缩小)的时候,其实是将之前left对应的值移出当前窗口,维护当前窗口的大小始终等于设定值。
对应到上面的程序就是

window =windowDelete(window,nums[left])
left++

windowDelete()方法是删除对应left的数据,之后left++维护窗口,之后其实是重复right-left+1 === k的操作
什么时候更新结果
这个需要根据题意,这道题是需要在每次窗口成立的时候获取中位数,同时还有可能每次窗口成立的时候获取窗口内所有数的最大值之类的,通常有使用Math.max()Math.min()来对比上个窗口与当前窗口的值取最大(最小)实现操作

总的来说
一般是在窗口扩展的时候进行数据操作,对应right++并且right - left + 1 < k的过程
然后当窗口达到设定大小的时候记录一次数据oldvalue,对应right - left + 1 === k的时候
之后因为right++窗口继续扩展
会导致窗口的大小大于设定对应right - left + 1 > k,就会进行窗口的缩小,对应的就是left++,实现left的右移,并且要将右移的数从原来的结果减掉,新right对应的数也要添加进结果,这样操作之后会产生一个新的值newvalue
根据需要处理oldvaluenewvalue即可
循环结束的标准是right >= length,当右指针移动到数组(字符串)最右端就结束循环

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,530评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,403评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,120评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,770评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,758评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,649评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,021评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,675评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,931评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,751评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,410评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,004评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,969评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,042评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,493评论 2 343

推荐阅读更多精彩内容