zoukankan      html  css  js  c++  java
  • 单调队列

    单调队列

    性质

    单调队列和单调栈很像,就是一个维护了单调性的队列数据结构,可以是单调递增的,也可以是单调递减的。

    模型

    下图是一个单调递增的单调队列模型。

    其中元素也是从小到大排列。
    和单调栈的操作一样,如果加入一个满足单调性的元素,例如5,那么就直接加入。

    那么如果加入一个元素3呢?我们维护单调性,需要把队列尾端把大于3的元素全部弹出,那么就需要用双端队列来实现了,当然操作和单调栈是一样的。

    单调队列有许多作用:

    比如可以求出一个数组内第一个大于等于一个数x的数

    也可以通过维护单调性,解决一些区间内最小或最大的问题

    总之单调队列的应用在根本上要视题目而定的灵活运用

    本质上并不复杂

    如果求最大,就维护单调递减的队列;如果求最小,就维护单调递增的队列

    题目描述

    现在有一堆数字共N个数字(N<=10^6),以及一个大小为k

    的窗口。现在这个从左边开始向右滑动,每次滑动一个单

    位,求出每次滑动后窗口中的最大值和最小值。

    例如:

    The array is [1 3 -1 -3 5 3 6 7], and k = 3.

    输入格式:

    输入一共有两行,第一行为n,k。

    第二行为n个数(<INT_MAX).

    输出格式:

    输出共两行,第一行为每次窗口滑动的最小值

    第二行为每次窗口滑动的最大值

    输入输出样例

    输入样例#1:

    8 3

    1 3 -1 -3 5 3 6 7

    输出样例#1:

    -1 -3 -3 -3 3 3

    3 3 5 5 6 7

    请用C++提交

    #include <stdio.h>
    #include <algorithm>
    #include <iostream>
    #include <stdbool.h>
    #include <stdlib.h>
    #include <string>
    #include <string.h>
    #include <math.h>
    #include <vector>
    #include <queue>
    #include <stack>
    #include <set>
    #include <map>
    
    #define INF 0x3f3f3f3f
    #define LL long long
    #define MAXN 2000005
    using namespace std;
    
    struct Node{
        int index;
        int val;
    };
    
    int a[MAXN];
    deque<Node> q;
    
    int main()
    {
        int n,m;
        Node node;
        scanf("%d%d",&n,&m);
        for (int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        for (int i=1;i<=n;i++)     // 区间最大值
        {
            node.val = a[i];
            node.index = i;
            while (!q.empty() && q.back().val<a[i])
                q.pop_back();
            q.push_back(node);
            if (i>=m)
            {
                while (!q.empty() && q.front().index+m<=i)
                    q.pop_front();
                printf("%d
    ",q.front().val);
            }
        }
        while (!q.empty())    //区间最小值
            q.pop_front();
        for (int i=1;i<=n;i++)
        {
            node.val = a[i];
            node.index = i;
            while (!q.empty() && a[i]<q.back().val)
                q.pop_back();
            q.push_back(node);
            if (i>=m)
            {
                if (!q.empty() && q.front().index+m<=i)
                    q.pop_front();
                printf("%d
    ",q.front().val);
            }
        }
        return 0;
    }
  • 相关阅读:
    MR案例:内连接代码实现
    分布式缓存DistributedCache
    MR案例:Map-Join
    hadoop随手笔记
    Job流程:决定map个数的因素
    Job流程:提交MR-Job过程
    MR案例:Reduce-Join
    MR案例:倒排索引
    MR案例:路径过滤PathFilter
    MR案例:分区和排序
  • 原文地址:https://www.cnblogs.com/-Ackerman/p/11276929.html
Copyright © 2011-2022 走看看