第20节 Sliding Window(deque双端队列)

第20节 Sliding Window
An array of size n ≤ 106 is given to you. 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 rightwards by one position. Following is an example:
The array is [1 3 -1 -3 5 3 6 7], and k is 3.
Window position Minimum value Maximum value
[1 3 -1] -3 5 3 6 7 -1 3
1 [3 -1 -3] 5 3 6 7 -3 3
1 3 [-1 -3 5] 3 6 7 -3 5
1 3 -1 [-3 5 3] 6 7 -3 5
1 3 -1 -3 [5 3 6] 7 3 6
1 3 -1 -3 5 [3 6 7] 3 7
Your task is to determine the maximum and minimum values in the sliding window at each position.

输入描述:
The input consists of two lines. The first line contains two integers n and k which are the lengths of the array and the sliding window. There are n integers in the second line.

输出描述:
There are two lines in the output. The first line gives the minimum values in the window at each position, from left to right, respectively. The second line gives the maximum values.
示例1
输入
8 3
1 3 -1 -3 5 3 6 7
输出
-1 -3 -3 -3 3 3
3 3 5 5 6 7


对于给定的数组,固定窗口的长度,滑动窗口,输出每一个窗口位置中,窗口内的最大值和最小值。
示例1
输入
8 3
1 3 -1 -3 5 3 6 7
输出
-1 -3 -3 -3 3 3
3 3 5 5 6 7

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1e6 + 117;
int n, k, a[MAXN];
deque<int> de;//双端队列
int main()
{
    scanf("%d%d", &n, &k);
    //单调递增队列 :保证队列头元素一定是当前队列的最小值,用于维护区间的最小值。
    for(int i = 1; i <= n; i++)
	{
        scanf("%d", &a[i]);
        //当队列不空且i在滑动窗口外时,弹出队首元素用if也可
        while(!de.empty() && de.front() + k - 1 < i) de.pop_front();
        //当队列不空且当前元素小于队尾元素,则挑选最小元素时比a[i]大的都用不上,将这些弹出
        while(!de.empty() && a[de.back()] > a[i]) de.pop_back();
        //当前元素进队
        de.push_back(i);
        //打印队首元素,打完换行,其余为空格
        if(i >= k) printf("%d%c", a[de.front()], i == n ? 10 : 32);
    }
    de.clear();
    //单调递减队列 :保证队列头元素一定是当前队列的最大值,用于维护区间的最大值。
    for(int i = 1; i <= n; i++)
	{
	
        while(!de.empty() && de.front() + k - 1 < i) de.pop_front();
        while(!de.empty() && a[de.back()] < a[i]) de.pop_back();
        de.push_back(i);
        if(i >= k) printf("%d%c", a[de.front()], i == n ? 10 : 32);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值