队列数组模拟队列和单调队列

Posted trevo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了队列数组模拟队列和单调队列相关的知识,希望对你有一定的参考价值。

数组模拟队列

用数组queue模拟队列,使用front和tail分别代表收尾指针,初始化front=0, tail=-1
    1. 入队:queue[++tail] = x
    2. 出队:++front
    3. 判空:front > tail 队列为空
    4. 获取队头元素: queue[front]

#include <iostream>
using namespace std;
const int N = 100010;
int queue[N], front, tail = -1;
int main()
{
    int m; 
    cin>>m;
    while(m--)
    {
        string op;
        int x;
        cin>>op;
        if(op == "push")
        {
            cin>>x;
            queue[++tail] = x;
        }
        else if(op == "pop")
        {
            if(front <= tail) ++front;
        }
        else if(op == "empty")
        {
            if(front > tail) cout<<"YES"<<endl;
            else cout<<"NO"<<endl;
        }
        else if(op == "query")
        {
            if(front <= tail) cout<<queue[front]<<endl;         
        }
    }
    return 0;
}

单调队列

考虑问题时,先考虑普通队列如何做,然后使用单调队列优化。
适用于两种问题:
    1. 滑动窗口min或max
    2. 离某个元素最近的值
维护一个单调队列,对头元素为滑动窗口最小的元素
    1. 判断当前对头是不是在窗口中
    2. 当前元素小于等于队尾元素时(对头元素最小),队尾元素出队
    3. 把当前元素下标出入队尾中
    4. 输出对头元素min

#include <iostream>
using namespace std;

const int N = 1000010;

int queue[N], arr[N], front = 0, tail = -1;

int main()
{
    int n, k;
    cin>>n>>k;
    
    for(int i = 0; i < n; i++)  cin>>arr[i];
    
    for(int i = 0; i < n; i++)
    {
        if(front <= tail && queue[front] < i - k + 1)   front++;
        while(front <= tail && arr[queue[tail]] >= arr[i])  tail--;
        queue[++tail] = i; 
        if(i + 1 >= k) cout<<arr[queue[front]]<<" ";
    }
    cout<<endl;
    front = 0, tail = -1;  //记得重新初始化对头和队尾
    for(int i = 0; i < n; i++)
    {
        if(front <= tail && queue[front] < i - k + 1) front++;
        
        while(front <= tail && arr[queue[tail]] <= arr[i]) tail--;
        
        queue[++tail] = i;
        
        if(i + 1 >= k) cout<<arr[queue[front]]<<" ";
        
    }
}

以上是关于队列数组模拟队列和单调队列的主要内容,如果未能解决你的问题,请参考以下文章

用数组模拟栈 队列 以及单调栈 单调队列应用

最大子序和(数组模拟单调队列)

poj 2823题解

⭐算法入门⭐《队列 - 单调队列》中等03 —— LeetCode 918. 环形子数组的最大和

⭐算法入门⭐《队列 - 单调队列》困难03 —— LeetCode 862. 和至少为 K 的最短子数组

HDU 3474 单调队列