当前位置:网站首页>11.滑动窗口的最大值——重要结构双端队列
11.滑动窗口的最大值——重要结构双端队列
2022-07-16 16:40:00 【123_YQH】
滑动窗口最大(小)值
1.滑动窗口最大值结构
窗口概念:一开始窗口左边界L、有边界R都停留在数组左侧,窗口L和R都只能往数组右边移动,并且左边界L永远不能超过有边界R。任何时刻都能选择让L或者R往右移动,但要时刻保持上述原则,这样不断移动的过程就形成了滑动窗口。
我们要解决的问题就是:每次用非常小的代价求得滑动窗口的最大值。
简单做法就是每次都遍历一遍滑动窗口,但这样代价就很高,有没有一种结构让每次求得滑动窗口最大值的代价很小?
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZJVTpAvF-1650945273422)(C:\Users\ThinkStation K\AppData\Roaming\Typora\typora-user-images\1650939959938.png)]](/img/18/c90f0fa5d44342d8bf0d1eed07f59b.png)
我们可以利用双端队列来实现这样的功能。
1.1滑动窗口最大值实现结构——双端队列
双端队列既可以从队头进出元素,也可以从队尾进出元素,我们用双端队列存放数组的下标,因为下标可以得到数组的值,还能得到值的位置,比单纯放入数组的值得到的信息更多。
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YblI6n20-1650945273422)(C:\Users\ThinkStation K\AppData\Roaming\Typora\typora-user-images\1650939459867.png)]](/img/49/186cfb656ece89c59edc4aaeadcf53.png)
双端队列从队头到队尾要保持里面下标对应的值是从大到小的,如何做到这一点,我们举个例子。
【例1】模拟数组[3 2 4 5 3]滑动窗口R移动时双端队列的变化
1.R往右移动一个元素,3元素下标从队尾进队列。

2.R往右移动一个元素,2元素的下标从队尾进入队列。

3.R再往右移动一个元素,元素4的下标试图从队尾进入,但如果进入将破坏双端队列从队头到队尾从大大小的规则,所以元素2的下标1从队尾出队列(出队列后永远不找回),循环往复直到满足规则时从队尾放入。
4.R再往右移动一个元素。6比4大,因此4元素对应的下标先从队尾出,6元素的下标从队尾进。

5.R再往右移动一个元素。6和6相等,但因为要遵循严格单调性,6元素对应的下标3先从队尾出,6元素对应的下标4从队尾进。

【例2】模拟数组[6 4 2 5 3]滑动窗口L移动时队列的变化
1.初始状态
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-riEnHcWY-1650945273424)(C:\Users\ThinkStation K\AppData\Roaming\Typora\typora-user-images\1650942310495.png)]](/img/07/0c0ca75fbee77790426eca59757a21.png)
2.L往右移动一个元素,发现0是双端队列头部元素,0从队头弹出。

3.L往右移动一个元素,发现1是队头元素,1从队头弹出。
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3U52g6UG-1650945273424)(C:\Users\ThinkStation K\AppData\Roaming\Typora\typora-user-images\1650942517615.png)]](/img/70/2dae484c28f2c41a4e0c2b17786e9a.png)
4.R向右移动两个元素。

5.L向右移动一个元素,发现2不是队头元素,队列保持不变。
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7dvY8em1-1650945273425)(C:\Users\ThinkStation K\AppData\Roaming\Typora\typora-user-images\1650942653769.png)]](/img/50/a7ca61980b3a4063703c63f713ae6f.png)
6.L向右移动一个元素,发现3是队头元素,3从队头弹出。
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MLgTztps-1650945273425)(C:\Users\ThinkStation K\AppData\Roaming\Typora\typora-user-images\1650942684779.png)]](/img/45/0f920f8d704a676504a5c3a8a5f30b.png)
于是我们可以知道双端队列移动时的策略:
- R向右移动时:如果双端队列队尾下标指向元素的值小于要弹入的值,则队尾依次弹出,直到队尾的值大于要弹入的值时,才弹入。(保持双端队列的严格单调性)。
- L向右移动时:如果要弹出的值就是队头元素,则队头元素弹出;否则双端队列保持不变。
双端队列维持信息的意义是:我们不让R移动,而是让L依次移动的话,谁会依次成为最大值这个信息。
1.2滑动窗口最大值实现代码
//与上述不同的是,这个双端队列存放的是数组的元素,而不是下标。但效果是一样的,存放下标实现会麻烦一点,如果直接放元素可以解决问题那就直接存放元素。
class MyQueue {
//双端队列
public:
deque<int> que;
//如果要弹出的元素等于队头元素直接弹出,否则保持不变。
void pop(int val) {
if (!que.empty() && val == que.front()) {
que.pop_front();
}
}
//如果要push的值大于队尾元素,队尾元素弹出,直到队尾元素的值大于要push的值或者双端队列为空。
//这样时为了保持双端队列从队头到队尾的严格单调递减
void push(int val) {
while (!que.empty() && que.back() < val) {
que.pop_back();
}
que.push_back(val);
}
//查询队列的最大值
int front() {
return que.front();
}
};
2.例题
239. 滑动窗口最大值
给定一个数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。
返回滑动窗口中的最大值。
进阶:
你能在线性时间复杂度内解决此题吗?

提示:
- 1 <= nums.length <= 10^5
- -10^4 <= nums[i] <= 10^4
- 1 <= k <= nums.length
class Solution {
public:
//与上述不同的是,这个双端队列存放的是数组的元素,而不是下标。
class MyQueue {
//双端队列
public:
deque<int> que;
//如果要弹出的元素等于队头元素直接弹出,否则保持不变。
void pop(int val) {
if (!que.empty() && val == que.front()) {
que.pop_front();
}
}
//如果要push的值大于队尾元素,队尾元素弹出,直到队尾元素的值大于要push的值或者双端队列为空。
//这样时为了保持双端队列从队头到队尾的严格单调递减
void push(int val) {
while (!que.empty() && que.back() < val) {
que.pop_back();
}
que.push_back(val);
}
//查询队列的最大值
int front() {
return que.front();
}
};
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
MyQueue que;
vector<int> res;
int left = 0, right = 0;
while (right < k) {
que.push(nums[right++]);
}
res.push_back(que.front());
while (right < nums.size()) {
que.push(nums[right++]);
que.pop(nums[left++]);
res.push_back(que.front());
}
return res;
}
};
边栏推荐
- solidity的代码
- 公司股权分配参考
- Ci521国产13.56MHz读写器芯片替代兼容CV520
- Dark horse programmer - software testing -15 stage 3- function testing 146-173 case review summary, tpshop project practice, state transition method cases, flow chart, business process testing, relati
- 低代码三部曲之起因
- 满电出行王颖:用数据安全护航智慧出行
- 困于营销围城中,“国货之光”这个称号花西子还能担多久?
- Singleton mode in QT: implement a singleton interface class
- Orm déchiqueté à la main (générique + annotation + réflexion)
- Unity video control pause playback and slider drag (notes)
猜你喜欢

SI24R2E_智能电子学生卡2.4GHz考勤方案芯片

马斯克76岁父亲与继女生子,华强北又出一个芯片IPO,原蚂蚁副总投身AI制药,今日更多大新闻在此...

阿里一面:SQL 优化有哪些技巧?

Win11 prompts what to do if this site is unsafe? Win11 prompt the solution of unsafe site

Dark horse programmer - software testing -14 stage 3- function testing -66-77 Zen introduction, product manager uses Zen, super administrator uses Zen, super administrator modifies security strategy,
![[200 routines OpenCV] 232. Méthode spectrale de caractérisation](/img/54/77f420654cc49723fbdbe845023ec8.png)
[200 routines OpenCV] 232. Méthode spectrale de caractérisation

airtest+poco多脚本、多设备批处理运行测试用例自动生成测试报告

分享不同,精彩纷呈 | 开发者说·DTalk 年中鉴赏

Jmeter常用功能-参数化介绍

九、MySQL锁机制 十、复制
随机推荐
SI24R2E_ Smart electronic student card 2.4GHz attendance scheme chip
渐隐渐现1920-500(7)
手撕ORM(泛型+注解+反射)
MQ简单介绍
PHP command execution garbled code solution (ThinkPHP)
【OpenCV 例程200篇】232. 特征描述之频谱方法
Sharing different, wonderful | developers say · mid year appreciation of dtalk
Win32-进程锁-进程异步-进程互斥-CreateMutex-OpenMutex-WaitForSingleObject-ReleaseMutex
安卓 Day 26 :数据库Two
Ci521 domestic 13.56MHz reader chip replaces cv520 compatible
[Solved]splunk the captain dose not share common baseline with 1 instance
RizomUV展UV使用记要
渐隐渐现1920-500(8)
六、关联查询优化、七 排序分组优化、八截取查询分析
Tensorflow speed entry
An Amway note taking tool -- Obsidian
Day 4 training
Tear ORM by hand (generic + annotation + reflection)
5道String高频面试题,拿捏String底层原理!
罗永浩:或2年后举行首场发布会,2000人年代码量是护城河