当前位置:网站首页>Sliding Window
Sliding Window
2022-07-28 11:49:00 【.DoubleBean.】
leetcode 239.Sliding Window Maximum
You are given an array of integers nums, there is a sliding window of size k which is moving from the very left of the array to the very right. You can only see the k numbers in the window. Each time the sliding window moves right by one position.
Return the max sliding window.
Example 1:
Input: nums = [1,3,-1,-3,5,3,6,7], k = 3
Output: [3,3,5,5,6,7]
Example 2:
Input: nums = [1], k = 1
Output: [1]
Example 3:
Input: nums = [1,-1], k = 1
Output: [1,-1]
Example 4:
Input: nums = [9,11], k = 2
Output: [11]
Example 5:
Input: nums = [4,-2], k = 2
Output: [4]
Constraints:
1 <= nums.length <= 105
-104 <= nums[i] <= 104
1 <= k <= nums.length
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/sliding-window-maximum
这题可以用双端单调队列来解决这道题:
因为在窗口向前滑动的过程中,我们会发现,每次窗口向前滑动的时候,要添加一个数的同时还要减少一个数,添加一个新的元素进去,如果这个新的元素比窗口内的一些数要大,那么这些比新元素要小的数,直到被淘汰都没有机会露个面。
eg: 序列 [10,7,5],6,4,3
在窗口向前滑动后,新数据6比5要大,那么,这个5直到被淘汰都不可能是最大的数,因为有个6一直打压 着它。
10,[7,5,6],4,3 ---------------------- Max = 7
10,7,[5,6,4],3 ---------------------- Max = 6
10,7,5,[6,4,3] ---------------------- Max = 6
那么我们可以在遍历一遍序列时,在压入一个新数据的时候,将之前比它小的所有数字,全都删除,只保留比它大的数字,那么最终得到的序列一定是个单调递减的序列,这就是单调队列。
那为什么要双端队列呢,因为在添加新数据进入队列,以及删除比新数据要小的数据都是在队尾实现,但要获得每次移动窗口后最大的数据的值,就得要队头元素,用queue.front()来获取,而且窗口向前滑动,得删除掉滑动窗口左端的元素,所以得用双端单调队列。
代码:
class Solution {
private:
deque<int> data; //double-ended queue
public:
void push(int DATA)
{
//在队尾添加元素,把前面比新元素小的元素都删除掉
while(!data.empty() && data.back() < DATA){
data.pop_back();
}
data.push_back(DATA);
} //形成单调递减序列
int max(){
return data.front(); }
void pop(int DATA){
/*滑动窗口向前移动一位,右边加一位,左边得减一位,但如果已经被压扁了, 也就是说队列里面已经不存在最左边的那个数,就不用删除,否则就得删除掉这个数*/
if(!data.empty() && data.front() == DATA){
data.pop_front();
}
};
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
Solution window;
vector<int> res;
for(int i = 0; i < nums.size(); i++){
if(i < k - 1){
//先填满窗口的前K - 1
window.push(nums[i]);
}
else{
//窗口向前滑动
window.push(nums[i]);
res.push_back(window.max());
window.pop(nums[i - k + 1]); //指滑动窗口最左边的数字,查看它是否在队列中,有则删除掉
}
}
return res;
}
};
洛谷P1886 滑动窗口 /【模板】单调队列
洛谷同样有这道题,只是多了个求最小值。思路是一样的。
输入 #1
8 3
1 3 -1 -3 5 3 6 7
输出 #1
-1 -3 -3 -3 3 3
3 3 5 5 6 7
链接:https://www.luogu.com.cn/problem/P1886
#include<iostream>
#include<deque>
#include<cstdio>
#include<vector>
using namespace std;
long long int res[1000001] = {
0 }, res1[1000001] = {
0 };
void push(deque<long long int>& line, long long int data, int flag)
{
if (flag == 1){
while (!line.empty() && line.back() < data)
line.pop_back();
line.push_back(data);
}
else{
while (!line.empty() && line.back() > data)
line.pop_back();
line.push_back(data);
}
}
void pop_data(deque<long long int>& line, long long int data)
{
if (!line.empty() && line.front() == data)
line.pop_front();
}
int main(){
deque<long long int> q, qq;
int i, n, k, len1 = 0, len2 = 0;
long long int xx;
vector<long long int> nums;
cin >> n >> k;
for (i = 0; i<n; i++){
cin >> xx;
nums.push_back(xx);
}
for (i = 0; i < n; i++){
if (i < k - 1){
push(q, nums[i], 1);
push(qq, nums[i], 2);
}
else{
push(q, nums[i], 1);
push(qq, nums[i], 2);
res[len1++] = q.front();
res1[len2++] = qq.front();
pop_data(q, nums[i - k + 1]);
pop_data(qq, nums[i - k + 1]);
}
}
for (i = 0; i<len2; i++)
printf("%lld ", res1[i]);
printf("\n");
for (i = 0; i<len1; i++)
printf("%lld ", res[i]);
return 0;
}
边栏推荐
- 新零售电商O2O模式解析
- Unity 安装 Device Simulator
- AsiaInfo technology released antdb7.0, a "Telecom grade" core transaction database, to help government and enterprises "trust" to create the future!
- Redis implements distributed locks
- 恋爱男女十禁
- IO流再回顾,深入理解序列化和反序列化
- leetcode:704二分查找
- First in the country! The two standards of "data product registration" formulated by insight technology and Shandong data were officially released
- Developing NES games with C language (cc65) 11. Metatiles
- Use json.stringify() to format data
猜你喜欢

Open source huizhichuang future | 2022 open atom global open source summit openatom openeuler sub forum was successfully held
![[cute new problem solving] climb stairs](/img/a2/fd2f21c446562ba9f0359988d97efe.png)
[cute new problem solving] climb stairs

30 years of open source community | 2022 open atom global open source summit 30 years of special activities of open source community were successfully held

西门子对接Leuze BPS_304i 笔记

New progress in the implementation of the industry | the openatom openharmony sub forum of the 2022 open atom global open source summit was successfully held

Localization, low latency, green and low carbon: Alibaba cloud officially launched Fuzhou data center

【一知半解】零值拷贝

FutureWarning: Indexing with multiple keys (implicitly converted to a tuple of keys) will be depreca

卸载 Navicat:正版 MySQL 官方客户端,真香!

leetcode:704二分查找
随机推荐
Introduction to resttemplate
Is it overtime to be on duty? Take up legal weapons to protect your legitimate rights and interests. It's time to rectify the working environment
HC-05蓝牙模块调试从模式和主模式经历
第九章 REST 服务安全
OpenAtom OpenHarmony分论坛圆满举办,生态与产业发展迈向新征程
Most of the interfaces of Tiktok are already available, and more interfaces are still open. Please look forward to it
FutureWarning: Indexing with multiple keys (implicitly converted to a tuple of keys) will be depreca
设计一个线程池
Four authentic postures after suffering and trauma, Zizek
How to build knowledge management system in enterprises and institutions
遭受痛苦和创伤后的四种本真姿态 齐泽克
图书馆自动预约脚本
新东方单季营收5.24亿美元同比降56.8% 学习中心减少925间
Redis implements distributed locks
Develop NES game (cc65) 07 and controller with C language (collision with spirit)
开源汇智创未来 | 2022 开放原子全球开源峰会 OpenAtom openEuler 分论坛圆满召开
Using Arduino to develop esp8266 to build a development environment
Developing NES games with C language (cc65) 06. Sprites
Redis实现分布式锁
Multiple items on a computer share a public-private key pair to pull the Gerrit server code