在maxSlidingWindow 函数中实现了单调队列算法,并在主函数中调用该函数找到输入序列中长度为 kk 的滑动窗口的最大值。 输出结果如下: //滑动窗口最大值为:3 3 3 2 4
答案是可以,这就要用到单调递减队列。 单调递减队列是这么一个队列,它的头元素一直是队列当中的最大值,而且队列中的值是按照递减的顺序排列的。我们可以从队列的末尾插入一个元素,可以从队列的两端删除元素。 1.首先看插入元素:为了保证队列的递减性,我们在插入元素v的时候,要将队尾的元素和v比较,如果队尾的元...
int main(){ cin >> n >> k; for(int i = 0; i < n; i ++) cin >> a[i]; for(int i = 0; i < n; i ++){ while(hh <= tt && q[hh] < i - k + 1) hh ++; while(hh <= tt && a[q[tt]] >= a[i]) tt --; q[++ tt] = i; if(i >= k - 1) cout <<...
我们用图像去抽象这个过程:这个域的圈定很像一个滑块在一个范围内移动,然后求出域中的最大值和最小值,这很像滑动窗口这道题 这道题我们可用单调队列来处理滑块区域的最值 有所区别的是,滑动窗口这道题区间是一维的,而这题的区间是二维 那么有没有一种办法将它拓展为二维呢?我们不妨先把它纵向扩展,并且...
(线段树)过滑动窗口 **上一次我们谈论单调队列,这样是可以过滑动窗口的 void slove_min() { int head=1,tail=0; for(int i=1;i<=n;i++) { while(head<=tail&&q[head]+k<=i) head++;//更新掉太老的元素 while(head<=tail&&a[q[tail]]>a[i])//更新掉头元素,让头元素最小...
我们分析下这个题目,滑动窗口每移动一次都要将原窗口中的元素弹出一个,压入一个,同时获取一个最大值。到这一步,我们能联想到什么样的数据结构呢?双向队列+优先级队列。如果我们使用一个优先级队列来做这个题目,毫无疑问是可以完成的。笔者一开始也是想使用优先级队列作为解题的方法。
有了这些前提,就可以动手设计这道题使用的数据结构(单调队列)了,其精巧地满足了我们的需求。在这个问题里,使用的是一个双端队列。 在窗口建立(从读入第一个数到读入第size(窗口的大小)个数)和滑动的过程中,我们维护一个队列 ,它的行为和正常的队列一致,但是会自动淘汰那些不可能作为最小/大值询问结果的元素。
单调队列的典型应用是在滑动窗口中寻找最大/最小值的问题。 单调队列和单调栈都是用于维护数据的单调性,但单调队列是双端队列,用于在滑动窗口中寻找最大/最小值,而单调栈是栈数据结构,用于寻找下一个更大/更小元素。 下面我们对单调栈进行深度解析
自己的思路:用缓存当前窗口三个最值的方法,来降低移出窗的、进入窗的值对最值的影响。 问题在于:不能保证前三个最值,全部匹配当前窗口的前三个最值。当前三个最值挨着的时候,往后挪动三个,最值丢失,只能比较的是新进来的三个当最值,而不能把前面部分的数值再重新考虑进来。
多重背包的优化:用单调队列维护滑动串口 r可以看作是拿完所有i物品后,剩下的体积余数,即r = j % v。 用g来维护总价值,q单调队列来维护体积。期间涉及滑动窗口的弹出,以及单调队列的去除冗余操作,代码不难,思路难想。 #include <iostream> #include <cstring> ...