这是我参与「第五届青训营 」伴学笔记创作活动的第-1 天
- 单调栈
#include<iostream>
#include<stack>
using namespace std;
stack<int> s;
int main(){
int n,x;
cin>>n;
for(int i=0;i<n;i++){
cin>>x;
while(!s.empty() && s.top()>=x) s.pop();
if(s.empty()) cout<<"-1"<<" ";
else cout<<s.top()<<" ";
s.push(x);
}
return 0;
}
- 滑动窗口
#include<iostream>
using namespace std;
const int N = 1e6+10;
int a[N],q[N];
int n,k;
int main(){
int hh=0,tt=-1;
cin>>n>>k;
for(int i=0;i<n;i++) cin>>a[i];
for(int i=0;i<n;i++){
// i是窗口的终点,i-k+1是窗口的起点,之所以用if,每次窗口往后移到一步,移动的是hh
if(hh<=tt && i-k+1>q[hh]) hh++;
// 如果队内元素比当前元素大则需要出队,这里注意是用队尾元素比较
while(hh<=tt && a[q[tt]]>=a[i]) tt--;
// 队列存的是下标,如果放在if后面会导致输出原来队里面的队头元素,手动模拟便知道.
q[++tt]=i;
// 只有第k-1个数才开始输出
if(i>=k-1) cout<<a[q[hh]]<<" ";
}
cout<<endl;
hh=0,tt=-1;
// 最大值就队列里就降序
for(int i=0;i<n;i++){
// i是窗口的终点,i-k+1是窗口的起点,之所以用if,每次窗口往后移到一步
if(hh<=tt && i-k+1>q[hh]) hh++;
// 如果队内元素比当前元素大则需要出队
while(hh<=tt && a[q[tt]]<a[i]) tt--;
// 队列存的是下标,如果放在if后面会导致输出原来队里面的队头元素,手动模拟便知道.
q[++tt]=i;
// 只有第k-1个数才开始输出
if(i>=k-1) cout<<a[q[hh]]<<" ";
}
return 0;
}