基础数据结构 (学习笔记)(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]]<<" "; }

浙公网安备 33010602011771号