栈
💡 核心思想
栈是一种后进先出(LIFO)的数据结构,只允许在栈顶进行插入和删除。在竞赛中,栈常用于括号匹配、表达式求值、单调栈(求下一个更大/更小元素)等问题。C++ STL 的 stack 或 vector 都可以实现。
单调栈是栈在竞赛中最经典的进阶应用。核心思想是维护一个栈,其中的元素保持单调递增或递减。常用于 $O(n)$ 时间内求每个元素左边/右边第一个比它大/小的元素位置。
🎯 直觉理解
undefined
📝 算法流程
- 基本操作:push, pop, top, empty
- 单调栈:维护单调性,不满足时弹出
- 应用:括号匹配、表达式求值、单调栈
$$\text{单调栈每个元素最多入栈出栈各一次:} O(n)$$
📊 复杂度分析
| 指标 | 复杂度 |
|---|---|
| 时间 | $O(n)$(每个元素最多出入栈一次) |
| 空间 | $O(n)$ |
💻 参考实现(C++)
C++ (C++17)
#include <bits/stdc++.h>
using namespace std;
// 单调栈:求每个元素右边第一个比它大的元素
int main() {
int n; cin >> n;
vector<int> a(n), ans(n, 0);
for (auto& x : a) cin >> x;
stack<int> stk; // 存下标
for (int i = 0; i < n; i++) {
while (!stk.empty() && a[stk.top()] < a[i]) {
ans[stk.top()] = i + 1; // 1-based 位置
stk.pop();
}
stk.push(i);
}
for (int x : ans) cout << x << " ";
return 0;
}⚠️ 常见坑点
单调栈弹出条件(< 还是 <=)影响结果
栈为空时 top() 会 RE
用 STL stack 时注意没有 clear() 方法
数组模拟栈时注意栈顶指针的维护
📚 相关题目
| 题目 | 来源 | 难度 | 备注 |
|---|---|---|---|
| P5788 单调栈 | 洛谷 | CSP-S | 单调栈模板 |
| P1739 表达式括号匹配 | 洛谷 | CSP-J | 栈的基本应用 |