算法模板复习 | 青训营笔记

21 阅读1分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第-1 天

  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;
}
  1. 滑动窗口
#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;
}