滑动窗口

滑动窗口

https://ac.nowcoder.com/acm/problem/50528

首先,单调队列具有两个性质
1.队列中的元素其对应在原来的列表中的顺序必须是单调递增的。
2.队列中元素的大小必须是单调递*(增/减/甚至是自定义也可以)
这个题是单调队列的模板题,因为范围最大时1e6,所以这里直接用数组来模拟队列即可。
1.维护队首(就是如果你已经是当前的m个之前那你就可以被删了,head++)
2.在队尾插入(每插入一个就要从队尾开始往前去除冗杂状态)

/*Keep on going Never give up*/
#pragma GCC optimize(3,"Ofast","inline")
#include <bits/stdc++.h>
const int maxn = 2e5+10;
const int MaxN = 0x3f3f3f3f;
const int MinN = 0xc0c0c00c;
typedef long long ll;
const int mod = 100000000;
using namespace std;
int q1[1000010],q2[1000010];
int a[1000010];
int head,top;
int n,k;
void imax(){
    head=1,top=0;
    for(int i=1;i<=n;i++){
        while(head<=top&&i-q1[head]+1>k) head++;
        while(head<=top&&a[q1[top]]<a[i]) top--;
        q1[++top]=i;
        if(i>=k) printf("%d ",a[q1[head]]);
    }
    printf("\n");
    return ;
}
void imin(){
    head=1,top=0;
    for(int i=1;i<=n;i++){
        while(head<=top&&i-q2[head]+1>k) head++;
        while(head<=top&&a[q2[top]]>a[i]) top--;
        q2[++top]=i;
        if(i>=k) printf("%d ",a[q2[head]]);
    }
    printf("\n");
    return ;
}

int main()
{

    cin>>n>>k;
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    imin();
    imax();
    return 0;
}
全部评论

相关推荐

不愿透露姓名的神秘牛友
10-05 10:13
已编辑
HHHHaos:让这些老登来现在秋招一下,简历都过不去
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务