1. Cartesian Tree 在数组上的 O(n) 构造中单调栈实现。
Cartesian Tree(笛卡尔树)如何在数组上 O(n) 构造?单调栈实现的具体过程与正确性依据是什么?
- 单调栈维护右链的构造流程
- 弹栈节点挂为新元素左子树
- 中序保下标、堆序保值的双不变量
用单调栈 O(n) 构造大根笛卡尔树:从左到右扫描数组,维护一个栈(栈内节点构成当前树的右链,值严格递减)。处理新元素 x 时,不断弹出栈顶值小于 x 的节点,最后一个被弹出的节点作为 x 的左子树根;若弹出后栈不空,x 作为新栈顶的右孩子;若栈空,x 成为新根。每个节点入栈出栈各一次,总复杂度 O(n)。
正确性依据:栈内右链始终保持两个不变量——中序遍历即数组顺序(左子树在前、根、右子树在后),堆序即值序(父值 ≥ 子值)。弹出操作把右链上较小者挂到 x 的左子树,恰好同时维持这两个不变量。该构造是 RMQ→LCA、直方图最大矩形等问题的公共前置步骤。
单调栈构造的实质是"维护右链 + 弹栈挂左子树",与"找最近更大/更小元素"的单调栈用法一脉相承,区别在于这里要建立树形结构;面试时手推一个小例子(如 [3,2,1,4])即可讲清全流程。