队列
队列
队列是一种先入先出的数据结构。
它像栈一样,也有数组和 STL 两种实现方法。
- 数组:
int h, t, que[N];
que[++t] = x; // 入队
h++; // 出队
int k = que[h]; // 访问队头
h = t = 0; // 清空队列
- STL:
queue<int> que;
que.push(x); // 入队
que.pop(); // 出队,此时队列不为空
int k = que.front(); // 访问队头,此时队列不为空
单调队列
我们先来看一道题:
给出一个长度为 \(n\) 的数组,输出每 \(k\) 个连续的数中的最大值。
首先,我们可以想到暴力,时间复杂度为 \(O(n \times k)\)。
但是,如果 \(n, k\) 都是 \(10 ^ 5\) 级别的数,是肯定会超时的,所以,我们需要单调队列来优化。
由于我们需要求的是最大值,所以,当队尾的元素比当前元素 \(x\) 还小的话,就直接把队尾的元素弹掉,再让 \(x\) 入队。
又因为我们需要维护的是长度为 \(k\) 的区间,所以,当 \(i\) 为右端点时,如果队头的元素 \(< i - k + 1\),就把队头弹掉。
void getmax() {
int h = 0, t = 0;
for (int i = 1; i < k; i++) {
while (h <= t && a[que[t]] <= a[i]) t--;
que[++t] = i;
}
for (int i = k; i <= n; i++) {
while (h <= t && a[que[t]] <= a[i]) t--;
que[++t] = i;
while (que[h] <= i - k) h++;
cout << a[que[h]] << ' ';
}
}