单调栈与单调队列算法总结
单调栈
知识概览
- 单调栈最常见的应用是找到每一个数离它最近的且比它小的数。
- 单调栈考虑的方式和双指针类似,都是先想一下暴力做法是什么,然后再挖掘一些性质如单调性,最终可以把目光集中在比较少的状态中,从而达到降低时间复杂度的作用,都是算法优化的一种手段。
- 对于
的情况,
更有可能是答案,因此将
删掉。最终,剩下的是严格单调上升的序列。
例题展示
题目链接
https://www.acwing.com/problem/content/832/
代码
#include <iostream> using namespace std; const int N = 100010; int n; int stk[N], tt; int main() { scanf("%d", &n); for (int i = 0; i < n; i++) { int x; scanf("%d", &x); while (tt && stk[tt] >= x) tt--; if (tt) printf("%d ", stk[tt]); else printf("-1 "); stk[++tt] = x; } return 0; }
单调队列
知识概览
- 单调队列最经典的一个应用是求一下滑动窗口里的最大值或最小值。
- 用数组模拟栈和队列的效率更高,这里用数组模拟。
例题展示
题目链接
https://www.acwing.com/problem/content/156/
代码
#include <iostream> using namespace std; const int N = 1000010; int n, k; int a[N], q[N]; int main() { scanf("%d%d", &n, &k); for (int i = 0; i < n; i++) scanf("%d", &a[i]); int hh = 0, tt = -1; for (int i = 0; i < n; i++) { // 判断队头是否已经滑出窗口 if (hh <= tt && i - k + 1 > q[hh]) hh++; while (hh <= tt && a[q[tt]] >= a[i]) tt--; q[++tt] = i; if (i >= k - 1) printf("%d ", a[q[hh]]); } puts(""); hh = 0, tt = -1; for (int i = 0; i < n; i++) { // 判断队头是否已经滑出窗口 if (hh <= tt && i - k + 1 > q[hh]) hh++; while (hh <= tt && a[q[tt]] <= a[i]) tt--; q[++tt] = i; if (i >= k - 1) printf("%d ", a[q[hh]]); } puts(""); return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理