【算法】滑动窗口问题

问题

有一个整型数组arr和一个大小为w的窗口从数组的最左边划到最右边,窗口每次向右滑动一个位置
如数组为[4,3,5,4,3,3,6,7],窗口大小为3时
[【4,3,5】,4,3,3,6,7]最大值是5
[4,【3,5,4】,3,3,6,7]最大值是5
[4,3,【5,4,3】,3,6,7]最大值是5
以此类推。。。。
数组长度为n窗口大小为w,则一共产生n-w+1个窗口最大值

输入:整型数组arr,窗口大小w
输出:一个长度为n-w+1的数组res,res[i]表示每种窗口状态下的最大值,上例应返回[5, 8, 8]。

思路分析

可以先把初始窗口的最大值记录下来,每次向右移动一个位置,就看看最大的元素有没有被移除如果被移除了,则需要能找到第二大的元素,因此不能仅仅保存最大的数,用一个队列来保存,从头到尾按大小排列,新加入的元素需要按照大小给一个排位(事实上,原本队列中的比新元素小的元素可以被舍弃,因为他们本来就比新元素前,比新元素先排除,不会再新元素移除后成为次大的元素)。

那么队列应该保存什么数据呢,可以有两种:

1:保存具体最大的数值,如果移出的元素等于队头的元素,就把队头元素排除(会不会出现这种情况:队列中有小于当前队头,但是在当前队头前面的值,在这个值排出时,因为他不是队头,没有被比较排除,然后在后面成为队头?不会,队列中其他元素不会有比队头前的值,根据上面的条件,现在队头的这个值在入队时就把队列中小于他的值舍弃掉了,队列中比当前队头大的值又会在前面被排除)

2:保存最大的数值的下标,如果队头元素位置已不在窗口则把队头排除

这道题我们利用双端队列来实现最大值的关心,首先生成双端队列qmax,qmax中存放的是数组arr的下标。
同时我们制定如下的规则:
假设遍历到arr[i],qmax的放入规则为:
1:如果qmax为空,直接把下标i放进qmax,放入过程结束。
2:如果qmax不为空,取出当前qmax队尾存放的下标,假设为j。
1):如果arr[j]>arr[i],直接把下标i放入qmax的队尾,放入过程结束。
2):如果arr[j]<=arr[i],把j从qmax中弹出,重复qmax的放入规则。
也就是说,如果qmax是空的,就直接放入当前位置,如果qmax不是空的,那么就判断qmax的对头元素中对应的arr元素是否比当前值大,如果不是,那么我们直接淘汰队头,因为队头元素就是最老的最前面的本身就是最先要被淘汰的数据。而如果不是,那么我们把刚才的新位置放入到qmax的队尾。
然后假设遍历到了arr[i],qmax的弹出规则为:
如果qmax对头的下标等于i-w,说明当前qmax对头的下标已经过期,弹出当前对头的下标即可。
比如,当前队中元素为0,1,2(都是数组的下标),然后此时i=3,w=

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值