算法技巧

单调栈

单调栈是一类套路:栈里的元素(或它们对应的值)始终保持单调,新元素入栈前把破坏单调性的元素都弹掉。最经典的应用是 “下一个更大元素”:对数组每个位置 i,求右边第一个比 a[i] 大的值。

思路

维护一个栈,里面存的是还没找到答案的索引,对应的值从底到顶严格递减。每来一个新元素 a[i]

  • 只要栈顶对应的值 a[top] < a[i],就把它弹出来——它的”下一个更大元素”就是当前的 a[i]
  • 反复弹直到栈顶 ≥ a[i] 或者栈空
  • i 压栈

扫完之后,栈里剩下的索引右边没有更大元素,输出 -1

关键看法:每个索引最多入栈一次、出栈一次。总操作 O(n)。如果不用栈,每个位置都向右扫一遍就是 O(n²)

复杂度

  • 时间:O(n)
  • 空间:O(n)(栈最大装 n 个)

在动画里看什么

  • 深蓝:当前正在处理的 a[i]暖红:刚刚被弹出栈(已经找到答案)的位置;绿色:已经填好答案;浅蓝:还在栈中等待
  • 数组下方是 out 数组,初始全 -1,被解决的位置填进对应的值
  • 底部的 stack 展示栈内容,深蓝色的是栈顶;可以观察到值始终从底到顶递减