GESP8-单调栈

单调栈

用等待区一次性解决“右边第一个更大”的问题。

一、先回答问题

结论

暴力是每个人向右找;单调栈改成“高个子出现时,统一解决前面比它矮的人”。

课堂安排

先抓住模型,再用一个小样例手推,最后把判断写成稳定的 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;
}
读代码重点

先看状态变量,再看核心判断,最后检查边界和输出格式。