大家好,这一期,我将带领大家学习一种算法竞赛中常用的数据结构 --- 单调队列
废话不多说,我们直接开始这一期的内容
一:什么是单调队列?

二:单调队列相关算法题
1. 题目一:【单调队列模板题】滑动窗口


cpp
#include <iostream>
#include <deque>
using namespace std;
const int N = 1e6 + 10;
int n, k;
int a[N];
int main()
{
cin >> n >> k;
for(int i = 1; i <= n; i++) cin >> a[i];
deque<int> q; // 存下标
// 窗口内最小值 - 单调递增的队列 - 存下标
for(int i = 1; i <= n; i++)
{
while(q.size() && a[q.back()] >= a[i]) q.pop_back();
q.push_back(i);
// 判断队列里面元素是否在合法窗口内
if(q.back() - q.front() + 1 > k) q.pop_front();
if(i >= k) cout << a[q.front()] << " ";
}
cout << endl;
// 窗口内最大值 - 单调递减的队列 - 存下标
q.clear();
for(int i = 1; i <= n; i++)
{
while(q.size() && a[q.back()] <= a[i]) q.pop_back();
q.push_back(i);
if(q.back() - q.front() + 1 > k) q.pop_front();
if(i >= k) cout << a[q.front()] << " ";
}
cout << endl;
return 0;
}
2. 题目二:质量检测

cpp
#include <iostream>
#include <deque>
using namespace std;
const int N = 1e6 + 10;
int n, m;
int a[N];
int main()
{
cin >> n >> m;
deque<int> q; // 单调递增的队列 - 存下标
for(int i = 1; i <= n; i++)
{
cin >> a[i];
while(q.size() && a[q.back()] >= a[i]) q.pop_back();
q.push_back(i);
if(q.back() - q.front() + 1 > m) q.pop_front();
if(i >= m) cout << a[q.front()] << endl;
}
return 0;
}
好的,今天的分享就先到这里了,谢谢大家!!!