什么是单调队列?
百度百科
单调队列,即单调递减或单调递增的队列。
单调队列能干什么?
实现快速寻找区间的最大值与最小值
如何实现单调队列?(这里使用了STL的deque)
①建立结构体
因为我们之后要判断队首的元素是不是已经超出了滚动窗口,所以得把每个值记录他原来的位置
struct node
{
int num,id;
};
②判断原来的队首是不是还在滚动窗口内(并且输出当前的队首)
if(q.front().id+m<i)
q.pop_front();
cout<<q.front().num<<"\n";
③对新进的数进行插入
(1)按照条件删除队尾的数,如果是单调增的单调序列那么删掉队尾大于等于当前值的值,这样求的就是滚动窗口内的最小值
(2)插入当前数据
while(!q.empty()&&q.back().num>=a[i])
q.pop_back();
q.push_back((node){a[i],i});
完整代码(洛谷 P1440 求m区间内的最小值)
#include <bits/stdc++.h>
using namespace std;
struct node
{
int num,id;
};
deque<node> q;
int a[2000005];
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)
cin>>a[i];
for(int i=1;i<=n;i++)
{
if(q.empty())
cout<<"0\n";
else
{
if(q.front().id+m<i)
q.pop_front();
cout<<q.front().num<<"\n";
}
while(!q.empty()&&q.back().num>=a[i])
q.pop_back();
q.push_back((node){a[i],i});
}
}