class Solution:
def verifyPreorder(self, preorder):
lower_bound = float('-inf')
stack = []
for value in preorder:
if value < lower_bound:
return False
while stack and value > stack[-1]:
lower_bound = stack.pop()
stack.append(value)
return True
class Solution {
public:
bool verifyPreorder(vector<int>& preorder) {
int lower_bound = INT_MIN;
vector<int> stack;
for (int value : preorder) {
if (value < lower_bound)
return false;
while (!stack.empty() && value > stack.back()) {
lower_bound = stack.back();
stack.pop_back();
}
stack.push_back(value);
}
return true;
}
};
class Solution {
public boolean verifyPreorder(int[] preorder) {
int lowerBound = Integer.MIN_VALUE;
int i = -1;
for (int value : preorder) {
if (value < lowerBound) return false;
while (i >= 0 && value > preorder[i]) {
lowerBound = preorder[i--];
}
preorder[++i] = value;
}
return true;
}
}
var verifyPreorder = function(preorder) {
let lowerBound = -Infinity;
let stack = [];
for (let value of preorder) {
if (value < lowerBound) return false;
while (stack.length && value > stack[stack.length - 1]) {
lowerBound = stack.pop();
}
stack.push(value);
}
return true;
};
Given an array preorder
of integers, determine if it can represent the preorder traversal of a binary search tree (BST).
preorder
is unique.preorder
.
Return True
if the sequence is a valid preorder traversal of a BST, otherwise return False
.
The problem asks us to check if a given sequence could be the preorder traversal of a BST. The naive approach would be to reconstruct all possible BSTs and compare their preorder traversals to the input, but this is computationally infeasible for large inputs.
Instead, we can leverage the properties of BSTs and preorder traversal:
The challenge is to efficiently check these constraints as we process the sequence, ideally in linear time and space.
We use a stack-based approach to simulate the preorder traversal and enforce BST constraints:
preorder
array:
False
(BST property violated).True
.
This approach works because the stack maintains the path from the root down to the current node, and the lower bound ensures that we don't revisit a left subtree after moving to a right subtree.
Let's use the input [5, 2, 1, 3, 6]
:
lower_bound = -∞
, stack = []
stack = [5]
stack = [5, 2]
stack = [5, 2, 1]
stack = [5, 3]
stack = [6]
All values processed without violating the lower bound. So, the sequence is a valid preorder traversal of a BST.
preorder
. Each element is pushed and popped at most once.By leveraging the properties of BSTs and preorder traversal, we efficiently verify a preorder sequence using a stack and a dynamic lower bound. This avoids brute-force tree reconstruction and achieves linear time and space. The key insight is to simulate the traversal path and enforce the BST property at each step, making the solution both elegant and optimal.