LeetCode 255: Verify Preorder Sequence in Binary Search Tree (Monotonic Stack)
LeetCode 255StackBSTToday we solve LeetCode 255 - Verify Preorder Sequence in Binary Search Tree.
Source: https://leetcode.com/problems/verify-preorder-sequence-in-binary-search-tree/
English
Problem Summary
Given an integer array, determine whether it can be the preorder traversal of a BST.
Key Insight
Use a monotonic decreasing stack to simulate ancestor path. A variable low stores the latest popped ancestor, which is the lower bound for upcoming nodes in the right subtree.
Algorithm
- Initialize low=-∞ and empty stack.
- For each value x: if x < low, invalid.
- While stack top is smaller than x, pop and update low.
- Push x.
Complexity Analysis
Time: O(n), each element is pushed/popped once.
Space: O(n).
Common Pitfalls
- Forgetting to enforce x < low invalidation.
- Using non-strict comparisons and breaking BST constraints.
Reference Implementations (Java / Go / C++ / Python / JavaScript)
class Solution {
public boolean verifyPreorder(int[] preorder) {
int low = Integer.MIN_VALUE;
Deque st = new ArrayDeque<>();
for (int x : preorder) {
if (x < low) return false;
while (!st.isEmpty() && x > st.peek()) {
low = st.pop();
}
st.push(x);
}
return true;
}
} func verifyPreorder(preorder []int) bool {
low := math.MinInt
st := []int{}
for _, x := range preorder {
if x < low {
return false
}
for len(st) > 0 && x > st[len(st)-1] {
low = st[len(st)-1]
st = st[:len(st)-1]
}
st = append(st, x)
}
return true
}class Solution {
public:
bool verifyPreorder(vector<int>& preorder) {
int low = INT_MIN;
vector<int> st;
for (int x : preorder) {
if (x < low) return false;
while (!st.empty() && x > st.back()) {
low = st.back();
st.pop_back();
}
st.push_back(x);
}
return true;
}
};class Solution:
def verifyPreorder(self, preorder: List[int]) -> bool:
low = -10**10
st = []
for x in preorder:
if x < low:
return False
while st and x > st[-1]:
low = st.pop()
st.append(x)
return True/**
* @param {number[]} preorder
* @return {boolean}
*/
var verifyPreorder = function(preorder) {
let low = -Infinity;
const st = [];
for (const x of preorder) {
if (x < low) return false;
while (st.length && x > st[st.length - 1]) {
low = st.pop();
}
st.push(x);
}
return true;
};中文
题目概述
给定一个整数数组,判断它是否可能是某棵二叉搜索树(BST)的前序遍历结果。
核心思路
用单调递减栈模拟当前祖先路径。变量 low 记录最近一次出栈的祖先值,它代表当前节点允许的最小下界。
算法步骤
- 初始化 low=-∞,栈为空。
- 遍历每个 x,若 x < low 直接返回 false。
- 当栈顶小于 x 时持续出栈,并更新 low。
- 将 x 入栈。
复杂度分析
时间复杂度:O(n),每个元素最多进栈出栈一次。
空间复杂度:O(n)。
常见陷阱
- 漏掉 x < low 的非法判断。
- 比较条件不严格导致 BST 约束被破坏。
多语言参考实现(Java / Go / C++ / Python / JavaScript)
class Solution {
public boolean verifyPreorder(int[] preorder) {
int low = Integer.MIN_VALUE;
Deque st = new ArrayDeque<>();
for (int x : preorder) {
if (x < low) return false;
while (!st.isEmpty() && x > st.peek()) {
low = st.pop();
}
st.push(x);
}
return true;
}
} func verifyPreorder(preorder []int) bool {
low := math.MinInt
st := []int{}
for _, x := range preorder {
if x < low {
return false
}
for len(st) > 0 && x > st[len(st)-1] {
low = st[len(st)-1]
st = st[:len(st)-1]
}
st = append(st, x)
}
return true
}class Solution {
public:
bool verifyPreorder(vector<int>& preorder) {
int low = INT_MIN;
vector<int> st;
for (int x : preorder) {
if (x < low) return false;
while (!st.empty() && x > st.back()) {
low = st.back();
st.pop_back();
}
st.push_back(x);
}
return true;
}
};class Solution:
def verifyPreorder(self, preorder: List[int]) -> bool:
low = -10**10
st = []
for x in preorder:
if x < low:
return False
while st and x > st[-1]:
low = st.pop()
st.append(x)
return True/**
* @param {number[]} preorder
* @return {boolean}
*/
var verifyPreorder = function(preorder) {
let low = -Infinity;
const st = [];
for (const x of preorder) {
if (x < low) return false;
while (st.length && x > st[st.length - 1]) {
low = st.pop();
}
st.push(x);
}
return true;
};
Comments