【每日一题】滑动窗口

滑动窗口

http://www.nowcoder.com/questionTerminal/b4d345a65640432db06ac978ccb6e23a

维护一个单调队列,以最小值为例,队首是最小值的下标,将新加入的元素加入到队尾,但要pop掉那些比新加入元素还要大的元素再加入队尾(即如果比队首最小值还要小将整个队列pop掉再加入队尾),但是队首元素不一定就是这个窗口的答案,它可能在窗口的左边,所以从队首开始pop掉那些下标比i-m还要小的元素,最大值同理;

#include <cstdio>
#include <queue>
using namespace std;
const int N = 1e6+10;
int n,m,a[N];
void mi_deque(){
    deque<int> q;
    for(int i = 0;i < n;i++){
        while(!q.empty()&&a[q.back()] > a[i]){
            q.pop_back();
        }
        q.push_back(i);
        while(!q.empty()&&q.front() <= i-m){
            q.pop_front();
        }
        if(i >= m-1){
            printf("%d ",a[q.front()]);
        }
    }
    puts("");
}
void mx_deque(){
    deque<int> q;
    for(int i = 0;i < n;i++){
        while(!q.empty()&&a[q.back()] < a[i]){
            q.pop_back();
        }
        q.push_back(i);
        while(!q.empty()&&q.front() <= i-m){
            q.pop_front();
        }
        if(i >= m-1){
            printf("%d ",a[q.front()]);
        }
    }
    puts("");
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i = 0;i < n;i++) scanf("%d",a+i);
    mi_deque();
    mx_deque();
    return 0;
}
全部评论

相关推荐

牛客771574427号:恭喜你,华杰
点赞 评论 收藏
分享
10-17 12:16
同济大学 Java
7182oat:快快放弃了然后发给我,然后让我也泡他七天最后再拒掉,狠狠羞辱他一把😋
点赞 评论 收藏
分享
评论
1
1
分享
牛客网
牛客企业服务