正文
一、特殊的队列
1. 双端队列
字面意思,可以对两端进行 pop 和 push 操作的队列
(1)手写双端队列简述
const int N = 1e6 + 10;— 队列大小int que[N], head, tail;— 队列,队首队尾指针head++;— 弹出队首que[--head] = data;— 数据data从队首入队que[head];— 读取队首数据tail--;— 弹出队尾que[++tail] = data;— 数据data从队尾入队
(2)STL双端队列
#include <deque>
dq[i]— 访问元素dq.front()— 返回队首dq.back()— 返回队尾dq.pop_back()— 弹出队尾dq.pop_front()— 弹出队首dq.push_back(e)— 元素e从队尾入队dp.push_front(e)— 元素e从队首入队
2. 单调队列与滑动窗口
洛谷P1886
题目解析
给定一串序列以及一个窗口大小,要求输出窗口中的最大值与最小值
思路分析
使用单调队列,分两次遍历该序列,时间复杂度 O ( 2 N ) O(2N) O(2N),第一次输出最小值,第二次输出最大值
输出最小值:
- 使用双端队列从队尾存入元素
- 当存入元素比队尾元素小的时候,就将队尾元素pop
- 直到该元素不再比队尾元素小时,再push进入该队列
- 存入数组下标,方便判断是否还在窗口中
- 从队首判断是否属于窗口范围,不属于就pop掉
- 最后输出队首即可,该元素就是 当前窗口中 的 最小值
输出最大值:
具体思路同上,不过在第二步第三步中得到比大小,要选取更大的值
AC代码
#include <bits/stdc++.h>
using namespace std;
#define ONLINE_JUDGE
const int N = 1000010;
int n, m;
int a[N];
deque<int> q;
inline void problem() {
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; ++i) scanf("%d", &

本文介绍了双端队列的概念,包括手写双端队列的基本操作和STL实现,并通过洛谷P1886题解详细阐述了单调队列在滑动窗口问题中的应用,以及如何利用单调队列解决hdu 1003的最大子序列和问题。
最低0.47元/天 解锁文章

被折叠的 条评论
为什么被折叠?



