基础数据结构 (学习笔记)(25.11.14)

基础数据结构 (学习笔记)

单调栈

概述

可以维护一个栈,然后维护一个保证单调的栈,在一个新元素加进来的时候,要依次对栈顶进行比较,如果比栈顶要小,就要弹出栈顶,否则可以直接去加入栈

实现

#include <bits/stdc++.h>
using namespace std;
const int N = 1e6*3+100;
int a[N], stck[N];
//ans用于记录这个数是被哪个数弹出的
//然后我们这个栈为了方便就直接维护一个下标
int ans[N];
int n;
int cnt=0;
int main() {
 cin>>n;
 a[n+1] = INT_MAX;
 //单调递减栈
 for (int i=1; i<=n; i++) {
     cin>>a[i];
     //此时去加入栈
     //如果栈顶比入栈元素小,就去跳出,然后跳出的元素被记录
     while (a[stck[cnt]]<a[i]&&cnt) {
         ans[stck[cnt]] = i;
         cnt--;
     }
     stck[++cnt] = i;
 }
 //需要考虑一下这里有没有没法跳出的
 for (int i=1; i<=n; i++) {
     cout<<ans[i]<<" ";
 }
 return 0;
}

要最后考虑一下有没有没法跳出的数据,去特殊判断一下或者用个很大或很小的东西去往出跳一下

单调队列

概述

使用一个单调性的队列,用来维护区间的最值

实现

队首用来保证元素的单调性,只在队尾加入,保证时间的单调性

#include <bits/stdc++.h>
using namespace std;
const int N = 1e6+10;
int n, k;
int a[N], q[N];
int main() {
 cin>>n>>k;
 for (int i=1; i<=n; i++) {
     cin>>a[i];
 }
 //去维护一个队列,保证两端长度,大小递增
 int l=1, r=0;
 for (int i=1; i<=n; i++) {
     //分别去进行队尾入和队首弹出
     while (l<=r && a[q[r]]>=a[i]) {
         r--;
     }
     while (l<=r && q[l]+k<=i) {
         l++;
     }
     q[++r]=i;
     if (i>=k) cout<<a[q[l]]<<" ";
 }
posted @ 2025-11-14 10:55  Yuriha  阅读(4)  评论(0)    收藏  举报