从0开始学算法--数据结构(2.4双端队列与单调队列)

Posted wz-archer

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从0开始学算法--数据结构(2.4双端队列与单调队列)相关的知识,希望对你有一定的参考价值。

双端队列是特殊的队列,它与队列不同的是可以将元素加入头或尾,可以从头或尾取出元素(滑稽-这部就是栈和队列结合了吗)。

c++标准库

头文件

#include<deque>

定义

deque<int>deq;

取出队头,尾元素

deq.pop_front();
deq.pop_back();

访问队头,尾元素

deq.front();
deq.back();

向队头,尾加入元素

deq.push_front(x);
deq.push_back(x);

单调队列是在队列的基础上使它保持有序,与单调栈类似,所以它反应的也是一个区间内的最值问题

例:poj-2823

技术图片



技术图片

 

 

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
#include <deque>
#include <map>

using namespace std;

const int maxn=1e6+10;
int a[maxn];
int b[maxn];

struct aa{
    int a;
    int i;
    aa(){}
    aa(int x,int y):a(x),i(y){}
};
deque<aa>x;

int n,m;

int main(){
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;i++){
        scanf("%d",&a[i]);
    }
    for(int i=0;i<m-1;i++){
        if(x.empty())x.push_back(aa(a[i],i));
        else{
            aa w=x.back();
            while(!x.empty()&&w.a>=a[i]){
                x.pop_back();
                if(!x.empty())
                    w=x.back();
            }
            x.push_back(aa(a[i],i));
        }
    }
    int k=0;
    for(int i=m-1;i<n;i++){
        aa w;
        if(!x.empty())w=x.front();
        while(!x.empty()&&w.i<=i-m){
                //printf("%d ",w.a);
            x.pop_front();
            if(!x.empty())
                w=x.front();
        }
        if(x.empty())x.push_back(aa(a[i],i));
        else{
            w=x.back();
            while(!x.empty()&&w.a>=a[i]){
                    //printf("%d ",w.a);
                x.pop_back();
                if(!x.empty())
                    w=x.back();
            }
            x.push_back(aa(a[i],i));
        }
        w=x.front();
        b[k++]=w.a;
    }
    for(int i=0;i<k;i++){
        if(i!=k-1)printf("%d ",b[i]);
        else printf("%d
",b[i]);
    }




    while(!x.empty())x.pop_back();

    for(int i=0;i<m-1;i++){
        if(x.empty())x.push_back(aa(a[i],i));
        else{
            aa w=x.back();
            while(!x.empty()&&w.a<=a[i]){
                x.pop_back();
                if(!x.empty())
                    w=x.back();
            }
            x.push_back(aa(a[i],i));
        }
    }

    k=0;
    for(int i=m-1;i<n;i++){
        aa w;
        if(!x.empty())w=x.front();
        while(!x.empty()&&w.i<=i-m){
                //printf("%d ",w.a);
            x.pop_front();
            if(!x.empty())
                w=x.front();
        }

        if(x.empty())x.push_back(aa(a[i],i));
        else{
            w=x.back();
            while(!x.empty()&&w.a<=a[i]){
                    //printf("%d ",w.a);
                x.pop_back();
                if(!x.empty())
                    w=x.back();
            }
            x.push_back(aa(a[i],i));
        }
        w=x.front();
        b[k++]=w.a;
    }
    for(int i=0;i<k;i++){
        if(i!=k-1)printf("%d ",b[i]);
        else printf("%d
",b[i]);
    }
    return 0;
}

以上是关于从0开始学算法--数据结构(2.4双端队列与单调队列)的主要内容,如果未能解决你的问题,请参考以下文章

数据结构与算法:双端队列

双端队列广搜

一起学数据结构与算法深度学习队列

Python数据结构与算法(3.5)——双端队列

从0开始学算法--数据结构(2.3队列)

单调队列