单调栈
用等待区一次性解决“右边第一个更大”的问题。
一、先回答问题
结论
暴力是每个人向右找;单调栈改成“高个子出现时,统一解决前面比它矮的人”。
课堂安排
先抓住模型,再用一个小样例手推,最后把判断写成稳定的 C++14 代码。
二、核心观察
模型
栈里存下标,且对应值从栈底到栈顶保持递减。
复杂度
每个下标最多入栈一次、出栈一次,所以总复杂度是 O(n)。
三、互动演示
四、自己选答案
问题 1:这题最关键的状态是什么?
五、手推结果
| 场景 | 栈类型 |
|---|---|
| 找右边第一个更大 | 维护递减栈 |
| 找右边第一个更小 | 维护递增栈 |
六、C++14 参考代码
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin >> n;
vector<int> a(n + 1), ans(n + 1, 0);
for (int i = 1; i <= n; i++) cin >> a[i];
stack<int> st;
for (int i = 1; i <= n; i++) {
while (!st.empty() && a[i] > a[st.top()]) {
ans[st.top()] = i;
st.pop();
}
st.push(i);
}
for (int i = 1; i <= n; i++) cout << ans[i] << ' ';
return 0;
}读代码重点
先看状态变量,再看核心判断,最后检查边界和输出格式。