#include <iostream>
using namespace std;
const int N = 100010;
int m;
int q[N], hh, tt = -1;//hh表示队头,tt表示队尾
int main()
{
cin >> m;
while (m -- )
{
string op;
int x;
cin >> op;
if (op == "push")
{
cin >> x;
q[ ++ tt] = x;//队尾插入
}
else if (op == "pop") hh ++ ;//弹出
else if (op == "empty") cout << (hh <= tt ? "NO" : "YES") << endl;
else cout << q[hh] << endl;
//判断是不是空的
//if(hh<tt)
// cout <<"不空";
// else
// cout << "空"
//取出队头尾元素
//q[hh];
//q[tt];
}
return 0;
}
单调队列《滑动窗口》
#include <iostream>
using namespace std;
const int N = 1000010;
// a 数组存储输入的数字,q 数组作为滑动窗口的双端队列
int a[N], q[N];
int main()
{
int n, k;
// 读取数组长度 n 和窗口大小 k
scanf("%d%d", &n, &k);
// 读取数组中的 n 个数字
for (int i = 0; i < n; i ++ ) scanf("%d", &a[i]);
// 计算滑动窗口的最小值
int hh = 0, tt = -1; // hh 为队列头,tt 为队列尾
for (int i = 0; i < n; i ++ )
{
// 移除队列中不在当前窗口范围内的元素
if (hh <= tt && i - k + 1 > q[hh]) hh ++ ;
// 从队列尾移除比当前元素大的元素
while (hh <= tt && a[q[tt]] >= a[i]) tt -- ;
// 将当前元素的索引加入队列尾
q[ ++ tt] = i;
// 当窗口大小达到 k 时,输出当前窗口的最小值
if (i >= k - 1) printf("%d ", a[q[hh]]);
}
puts(""); // 换行
// 计算滑动窗口的最大值
hh = 0, tt = -1; // 重置队列头和尾
for (int i = 0; i < n; i ++ )
{
// 移除队列中不在当前窗口范围内的元素
if (hh <= tt && i - k + 1 > q[hh]) hh ++ ;
// 从队列尾移除比当前元素小的元素
while (hh <= tt && a[q[tt]] <= a[i]) tt -- ;
// 将当前元素的索引加入队列尾
q[ ++ tt] = i;
// 当窗口大小达到 k 时,输出当前窗口的最大值
if (i >= k - 1) printf("%d ", a[q[hh]]);
}
puts(""); // 换行
return 0;
}
// 执行过程:
// 计算最小值:
// 初始时,队列 q 是空的,hh 为 0,tt 为 -1。
// 遍历 a 数组:
// i = 0: a[i] = 1,队列为空,将 i 0 加入队列 q。队列 [0]。窗口小于 k,继续。
// i = 1: a[i] = 3,将 i 1 加入队列 q。队列 [0, 1]。窗口小于 k,继续。
// i = 2: a[i] = -1,将队列尾的元素(索引 1)移除,因为 a[1] >= -1。将 i 2 加入队列 q。队列 [0, 2]。窗口已满,输出最小值 a[0] = 1。
// i = 3: a[i] = -3,将队列尾的元素(索引 2)移除,因为 a[2] >= -3。将 i 3 加入队列 q。队列 [3]。输出最小值 a[3] = -3。
// i = 4: a[i] = 5,将 i 4 加入队列 q。队列 [3, 4]。输出最小值 a[3] = -3。
// i = 5: a[i] = 3,将 i 5 加入队列 q。队列 [3, 4, 5]。移除队列头元素,因为窗口不再包含索引 3。输出最小值 a[4] = -3。
// i = 6: a[i] = 6,将 i 6 加入队列 q。队列 [4, 5, 6]。输出最小值 a[5] = 3。
// i = 7: a[i] = 7,将 i 7 加入队列 q。队列 [5, 6, 7]。输出最小值 a[6] = 3。
// 最终最小值序列为: -1 -3 -3 -3 3 3
// 计算最大值:
// 初始时,队列 q 是空的,hh 为 0,tt 为 -1。
// 遍历 a 数组:
// i = 0: a[i] = 1,队列为空,将 i 0 加入队列 q。队列 [0]。窗口小于 k,继续。
// i = 1: a[i] = 3,将队列尾的元素(索引 0)移除,因为 a[0] < 3。将 i 1 加入队列 q。队列 [1]。窗口小于 k,继续.
// i = 2: a[i] = -1,将 i 2 加入队列 q。队列 [1, 2]。窗口已满,输出最大值 a[1] = 3。
// i = 3: a[i] = -3,将 i 3 加入队列 q。队列 [1, 2, 3]。移除队列头元素,因为窗口不再包含索引 1。输出最大值 a[2] = -1。
// i = 4: a[i] = 5,将队列尾的元素(索引 3)移除,因为 a[3] < 5。将 i 4 加入队列 q。队列 [4]。输出最大值 a[4] = 5。
// i = 5: a[i] = 3,将 i 5 加入队列 q。队列 [4, 5]。输出最大值 a[4] = 5。
// i = 6: a[i] = 6,将队列尾的元素(索引 5)移除,因为 a[5] < 6。将队列尾的元素(索引 4)移除,因为 a[4] < 6。将 i 6 加入队列 q。队列 [6]。输出最大值 a[6] = 6。
// i = 7: a[i] = 7,将队列尾的元素(索引 6)移除,因为 a[6] < 7。将 i 7 加入队列 q。队列 [7]。输出最大值 a[7] = 7。
// 最终最大值序列为: 3 3 5 5 6 7