单调栈、单调队列
单调栈
#include<bits/stdc++.h>
using namespace std;
using ll=long long;
const int N=2e5+9;
ll a[N];
ll l[N];
int main()
{
int n;cin>>n;
for(int i=1;i<=n;i++)cin>>a[i];
stack<int>stk;
for(int i=1;i<=n;i++)
{
while(stk.size()&&stk.top()>=a[i])stk.pop();//如果前边的数比后边要加进来的数大或等于,就出栈
if(stk.empty())l[i]=-1;//栈空说明没有比要加进来的数小的数
else
{
l[i]=stk.top();//如果栈不为空,说明栈顶元素就是第一个比要加进来数小的数
}
stk.push(a[i]);//将数入栈
}
for(int i=1;i<=n;i++)
{
cout<<l[i]<<' ';
}
return 0;
}
单调队列
#include<bits/stdc++.h>
using namespace std;
using ll=long long;
const int N=2e5+9;
ll a[N];
int main()
{
int n,k;cin>>n>>k;
for(int i=1;i<=n;i++)cin>>a[i];
//构造deque队列
//以i为右端点[i-k+1,i]
deque<int>dq;
for(int i=1;i<=n;i++)
{
//判断队头合法性
while(dq.size()&&dq.front()<=i-k)dq.pop_front();//判断队头元素是否在当前滑动窗口内,如果不在,则将队头元素弹出。
//判断队尾优越性
while(dq.size()&&a[dq.back()]<=a[i])dq.pop_back();//维护队列的单调性,若队尾元素小于等于当前元素,则将队尾元素弹出。
dq.push_back(i);
if(i>=k)cout<<a[dq.front()]<<' ';
}
cout<<'\n';
//清空容器
while(dq.size())
{
dq.pop_front();
}
//求最小值
for(int i=1;i<=n;i++)
{
while(dq.size()&&dq.front()<=i-k)dq.pop_front();
while(dq.size()&&a[dq.back()]>a[i])dq.pop_back();
dq.push_back(i);
if(i>=k)cout<<a[dq.front()]<<' ';
}
return 0;
}