Verify Preorder Sequence in Binary Search Tree
Given an array of numbers, verify whether it is the correct preorder traversal sequence of a binary search tree.
You may assume each number in the sequence is unique.
Example 1:

Input: preorder = [5,2,1,3,6]
Output: true
Follow up: Could you do it using only constant space complexity?
My Solutions:
此题和#98题很像,但是需要从数组中找到根节点、左子树和右子树。 按照#98的思路,从根节点开始每个节点维护一个范围,随着递归调用一直往下传递,只有所有数都落在指定范围内才是一棵有效二叉搜索树。
Time: O(n); Space: O(h), h = tree's height
public class Solution {
int index;
public boolean verifyPreorder(int[] preorder) {
helper(preorder, Integer.MIN_VALUE, Integer.MAX_VALUE);
return index == preorder.length;
}
private void helper(int[] preorder, int min, int max) {
if (index == preorder.length) return;
int val = preorder[index];
if (min < val && val < max) {
index++;
helper(preorder, min, val);
helper(preorder, val, max);
}
}
}
根据前序遍历的特点,根节点就是第一个数,如果找到第一个大于根节点值的数的位置,前半部就是左子树,右半部就是右子树。因此使用一个单调递减堆栈。
先设一个最小值low,然后遍历数组,如果当前值小于这个low,返回false。从数组第一个数开始只要是递减的就压入堆栈中,说明每个数都落在之前所有节点的左子树中。当碰到第一个比堆栈顶部大的数,说明当前这个数是堆栈中某一个节点的右子节点。此时弹出所有比这个数小的节点,并且更新low,然后把当前节点压入栈中。这样如果遍历完整个数组都没有返回false的话,返回true。
public boolean verifyPreorder(int[] preorder) {
int low = Integer.MIN_VALUE;
Stack<Integer> stack = new Stack<>();
for (int p : preorder) {
if (p < low) return false;
while (!stack.isEmpty() && p > stack.peek()) low = stack.pop();
stack.push(p);
}
return true;
}
这个方法还可以进一步优化,不使用 stack,直接修改 preorder,将 low 值存在 preorder 的特定位置,前提是不能影响当前的遍历。
public boolean verifyPreorder(int[] preorder) {
int low = Integer.MIN_VALUE, index = -1;
for (int p : preorder) {
if (p < low) return false;
while (index >= 0 && p > preorder[index]) {
low = preorder[index];
index--;
}
index++;
preorder[index] = p;
}
return true;
}
Last updated