zoukankan      html  css  js  c++  java
  • 数据结构:单调队列

    单调队列的作用,归纳成一句话就是不断读入元素,不时去掉元素,随时查询最值

    应用的话就比较高级了,除了滑动窗口这个题目,还有动态规划的效率优化,当然还有别的以后再整理

    单调队列由于要不断从两端进行队列操作,所以采用双端队列来实现

    在此例中,所有的数据都是放在a数组中的,我们用一个p来表示a数组中某一个元素的下标,然后在单调队列中存下标即可

    我们以维护单调递增队列举例

    while(!q.empty()&&a[p]<=a[q.back()])  //维护单调队列 
                q.pop_back();
            q.push_back(p);

    对于一个新的p,我们用a[p]和当前单调队列的最后一个位置的元素作比较,如果发现比新插入元素的大的,全部扔出去,因为我这个队列只维护单调增,只方便找最小值即可,大的没用

    然而,对于一些过期的元素,虽然他们很小,我们还是要把它们扔掉才可以

    while(!q.empty()&&q.front()<p-k+1)  //维持题意的区间长度 
                q.pop_front();  //移出出界的元素 

    接下来根据题意输出队列中元素的值即可

    由于我们是单调递增队列,维护的是最小值,那么队首元素就是最有用的

    if(p>=k-1)  //元素进够k个后开始输出答案 
                cout<<a[q.front()]<<" ";
            p++; 

    下面给出滑动窗口的完整实现

     1 //aininot260
     2 //不断读入元素,不时去掉元素,随时询问最值
     3 #include<iostream>
     4 #include<queue>
     5 using namespace std;
     6 const int maxn=1000005;
     7 int n,k;
     8 int a[maxn];
     9 deque<int> q;
    10 int main()
    11 {
    12     cin>>n>>k;
    13     for(int i=0;i<n;i++)
    14         cin>>a[i];
    15     int p=0;
    16     while(p<n)
    17     {
    18         while(!q.empty()&&a[p]<=a[q.back()])  //维护单调队列 
    19             q.pop_back();
    20         q.push_back(p);
    21         while(!q.empty()&&q.front()<p-k+1)  //维持题意的区间长度 
    22             q.pop_front();  //移出出界的元素 
    23         if(p>=k-1)  //元素进够k个后开始输出答案 
    24             cout<<a[q.front()]<<" ";
    25         p++; 
    26     }
    27     cout<<endl;
    28     
    29     p=0;
    30     q.clear();
    31     while(p<n)
    32     {
    33         while(!q.empty()&&a[p]>=a[q.back()])  //维护单调队列 
    34             q.pop_back();
    35         q.push_back(p);
    36         while(!q.empty()&&q.front()<p-k+1)  //维持题意的区间长度 
    37             q.pop_front();  //移出出界的元素 
    38         if(p>=k-1)  //元素进够k个后开始输出答案 
    39             cout<<a[q.front()]<<" ";
    40         p++; 
    41     }
    42     cout<<endl;
    43     return 0;
    44 } 
  • 相关阅读:
    Tornado web 框架
    mysql_orm模块操作数据库(17.6.29)
    mysql小结篇3 索引、分页、执行计划--(17.6.28)
    Oracle触发器Trigger2行级
    Oracle触发器Trigger基础1
    Oracle函数function
    Oracle异常的抛出处理
    Oracle利用过程procedure块实现银行转账
    Oracle存储过程procedure
    PL/SQL块loop..各种循环练习
  • 原文地址:https://www.cnblogs.com/aininot260/p/9304573.html
Copyright © 2011-2022 走看看