[LeetCode] 255. Verify Preorder Sequence in Binary Search Tree

Given an array of unique integers preorder, return true if it is the correct preorder traversal sequence of a binary search tree.

Example 1:

Input: preorder = [5,2,1,3,6]
Output: true

Example 2:

Input: preorder = [5,2,6,1,3]
Output: false

Constraints:

  • 1 <= preorder.length <= 104
  • 1 <= preorder[i] <= 104
  • All the elements of preorder are unique.

Follow up: Could you do it using only constant space complexity?

验证前序遍历序列二叉搜索树。

给定一个 无重复元素 的整数数组 preorder , 如果它是以二叉搜索树的先序遍历排列,返回 true 。

因为是二叉搜索树,所以左孩子 < 根节点 < 右孩子,同时左子树越往下,节点值越小;右子树是越来越大的(之于他的根节点)。总结下来就是局部递减,总体递增。这个题可以用单调栈的思路去做。为什么会有这个思路是因为原则上BST的前序遍历,一开始只会是越来越小,所以无条件加入stack;当你突然遍历到一个比较大的元素 X的时候,很有可能是某一个节点的左子树遍历完了要开始遍历这个节点的右子树了,因为右子树的 val 一定大于其左子树的 val 和根节点的 val,所以此时 stack 中所有小于 X 的元素(没有等于是因为题目说了元素都是 unique 的)都应该被 pop 出来,同时用一个变量 max 记录一下最后一个被 pop 出来的 val,他是当前这棵子树的根节点,因为之后无论加入什么 val,都一定要大于这个 max,否则就不是 BST 了。

具体实现方式是,首先设置一个变量 max 记录从 stack 中弹出的最大元素。将 input 里的元素按顺序加入 stack,如果 stack 不为空且当前待加入的元素大于栈顶元素,那么需要开始 pop 出来所有比当前元素小的元素;在遍历过程中,如果发觉有任何一个元素小于 max 则返回 false。

比如第一个例子,我们一开始遍历 5,2,1 都是递减的,正常入栈。此时我们下一个元素是 3,大于刚才的最后一个元素 1,那么说明如果这棵树是一个正常的 BST,这个 3 应该是某个右孩子节点。所以我们现在从单调栈里开始弹出元素,把所有小于 3 的元素都抛弃,最后一个被抛弃的元素(2)应该就是 3 的父节点。下一个元素是 6,又大于节点 3,,说明他应该又是一个右孩子。那么我们再次弹出单调栈中所有小于 6 的元素,最后一个被弹出的元素是5,5 也就是 6 的父节点。遍历完毕,这棵树是一个合法的BST。

时间O(n)

空间O(n)

Java实现

 1 class Solution {
 2     public boolean verifyPreorder(int[] preorder) {
 3         Stack<Integer> stack = new Stack<>();
 4         int max = Integer.MIN_VALUE;
 5         for (int cur : preorder) {
 6             while (!stack.isEmpty() && cur > stack.peek()) {
 7                 max = stack.pop();
 8             }
 9             if (cur < max) {
10                 return false;
11             }
12             stack.push(cur);
13         }
14         return true;
15     }
16 }

 

LeetCode 题目总结

posted @ 2020-05-02 02:38  CNoodle  阅读(161)  评论(0编辑  收藏  举报