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.

Consider the following binary search tree:

     5
/ \
2 6
/ \
1 3

Example 1:

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

Example 2:

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

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

这道题让给了一个一维数组,让我们验证其是否为一个二叉搜索树的先序遍历出的顺序,二叉搜索树的性质是左<根<右,如果用中序遍历得到的结果就是有序数组,而先序遍历的结果就不是有序数组了,但是难道一点规律都没有了吗,其实规律还是有的,根据二叉搜索树的性质,当前节点的值一定大于其左子树中任何一个节点值,而且其右子树中的任何一个节点值都不能小于当前节点值,可以用这个性质来验证,举个例子,比如下面这棵二叉搜索树:

    / \

  / \
    

其先序遍历的结果是 {5, 2, 1, 3, 6},先设一个最小值 low,然后遍历数组,如果当前值小于这个最小值 low,返回 false,对于根节点,将其压入栈中,然后往后遍历,如果遇到的数字比栈顶元素小,说明是其左子树的点,继续压入栈中,直到遇到的数字比栈顶元素大,那么就是右边的值了,需要找到是哪个节点的右子树,所以更新 low 值并删掉栈顶元素,然后继续和下一个栈顶元素比较,如果还是大于,则继续更新 low 值和删掉栈顶,直到栈为空或者当前栈顶元素大于当前值停止,压入当前值,这样如果遍历完整个数组之前都没有返回 false 的话,最后返回 true 即可,参见代码如下:

解法一:

class Solution {
public:
bool verifyPreorder(vector<int>& preorder) {
int low = INT_MIN;
stack<int> s;
for (auto a : preorder) {
if (a < low) return false;
while (!s.empty() && a > s.top()) {
low = s.top(); s.pop();
}
s.push(a);
}
return true;
}
};

下面这种方法和上面的思路相同,为了使空间复杂度为常量,我们不能使用 stack,所以直接修改 preorder,将 low 值存在 preorder 的特定位置即可,前提是不能影响当前的遍历,参见代码如下:

解法二:

class Solution {
public:
bool verifyPreorder(vector<int>& preorder) {
int low = INT_MIN, i = -;
for (auto a : preorder) {
if (a < low) return false;
while (i >= && a > preorder[i]) {
low = preorder[i--];
}
preorder[++i] = a;
}
return true;
}
};

下面这种方法使用了分治法,跟之前那道验证二叉搜索树的题 Validate Binary Search Tree 的思路很类似,在递归函数中维护一个下界 lower 和上界 upper,那么当前遍历到的节点值必须在 (lower, upper) 区间之内,然后在给定的区间内搜第一个大于当前节点值的点,以此为分界,左右两部分分别调用递归函数,注意左半部分的 upper 更新为当前节点值 val,表明左子树的节点值都必须小于当前节点值,而右半部分的递归的 lower 更新为当前节点值 val,表明右子树的节点值都必须大于当前节点值,如果左右两部分的返回结果均为真,则整体返回真,参见代码如下:

解法三:

class Solution {
public:
bool verifyPreorder(vector<int>& preorder) {
return helper(preorder, , preorder.size() - , INT_MIN, INT_MAX);
}
bool helper(vector<int>& preorder, int start, int end, int lower, int upper) {
if (start > end) return true;
int val = preorder[start], i = ;
if (val <= lower || val >= upper) return false;
for (i = start + ; i <= end; ++i) {
if (preorder[i] >= val) break;
}
return helper(preorder, start + , i - , lower, val) && helper(preorder, i, end, val, upper);
}
};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/255

类似题目:

Binary Tree Preorder Traversal

Validate Binary Search Tree

参考资料:

https://leetcode.com/problems/verify-preorder-sequence-in-binary-search-tree/

https://leetcode.com/problems/verify-preorder-sequence-in-binary-search-tree/discuss/68142/Java-O(n)-and-O(1)-extra-space

https://leetcode.com/problems/verify-preorder-sequence-in-binary-search-tree/discuss/68185/C%2B%2B-easy-to-understand-solution-with-thought-process-and-detailed-explanation

LeetCode All in One 题目讲解汇总(持续更新中...)

[LeetCode] 255. Verify Preorder Sequence in Binary Search Tree 验证二叉搜索树的先序序列的更多相关文章

  1. [LeetCode] Verify Preorder Sequence in Binary Search Tree 验证二叉搜索树的先序序列

    Given an array of numbers, verify whether it is the correct preorder traversal sequence of a binary ...

  2. Leetcode 255. Verify Preorder Sequence in Binary Search Tree

    验证一个list是不是一个BST的preorder traversal sequence. Given an array of numbers, verify whether it is the co ...

  3. [CareerCup] 4.5 Validate Binary Search Tree 验证二叉搜索树

    4.5 Implement a function to check if a binary tree is a binary search tree. LeetCode上的原题,请参见我之前的博客Va ...

  4. 第33题:LeetCode255 Verify Preorder Sequence in Binary Search Tree 验证先序遍历是否符合二叉搜索树

    题目 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则输出Yes,否则输出No.假设输入的数组的任意两个数字都互不相同. 考点 1.BST 二叉搜索树 2.递归 思路 1.后序 ...

  5. [LeetCode] Validate Binary Search Tree 验证二叉搜索树

    Given a binary tree, determine if it is a valid binary search tree (BST). Assume a BST is defined as ...

  6. [LeetCode] 98. Validate Binary Search Tree 验证二叉搜索树

    Given a binary tree, determine if it is a valid binary search tree (BST). Assume a BST is defined as ...

  7. [LeetCode] 255. Verify Preorder Sequence in Binary Search Tree_Medium tag: Preorder Traversal, tree

    Given an array of numbers, verify whether it is the correct preorder traversal sequence of a binary ...

  8. 255. Verify Preorder Sequence in Binary Search Tree

    题目: Given an array of numbers, verify whether it is the correct preorder traversal sequence of a bin ...

  9. [LC] 255. Verify Preorder Sequence in Binary Search Tree

    Given an array of numbers, verify whether it is the correct preorder traversal sequence of a binary ...

随机推荐

  1. 解决用navicat远程连接数据库出现1045 access denied for user 'root'@'localhost' using password yes

    在mysql命令行中执行 SET PASSWORD FOR 'root'@'localhost' = PASSWORD('123456XXX');  GRANT ALL PRIVILEGES ON * ...

  2. IDEA设置外部比对工具Beyond Compare

    设置IDEA使用外部的比对工具,比如Beyond Compare,其实很简单,但是可能好几年才会设置一次,比如换工作的时候,所以记录下来 可以通过菜单File-Settings 或者直接快捷键ctrl ...

  3. MySQL5.8下载及安装——免安装版

    1.下载MySQL5.8下载地址:https://dev.mysql.com/downloads/mysql/ 图一: 图二: 2.如何安装.配置mysql-8.0.17-winx64.zip下载完成 ...

  4. c# sqlserver 删除大批量数据超时

    我做的项目有个功能需要进行批量删除,删除的数据量有4.5W条数据. 通过下面的sql语句删除这么多数据,直接导致结果超时,无法删除数据. ,,,......) 我查了一些资料,可能找的不全,找到了一个 ...

  5. c# 修改系统日期格式

    引用 using System.Runtime.InteropServices; [DllImport("kernel32.dll", EntryPoint = "Get ...

  6. array list 的特点及几种遍历方法

    public class temp { public static void main(String[] args)throws Exception { //ArrayList 在定义时长度为空 ,在 ...

  7. Windows下实现应用程序看门狗软件

    有时候,我们需要确保一个应用程序长期稳定地运行,但是在Windows平台上由于种种原因,几乎不可能保障一个应用的绝对可靠运行.那么,我们就需要有一个机制,在应用死机﹑异常﹑系统重启等情况下自我恢复,而 ...

  8. delphi webbrowser用法集锦

    delphi webbrowser用法集锦 (2012-05-13 08:29:00) 标签: it 分类: 软件_Software WebBrowser1.GoHome; //到浏览器默认主页 We ...

  9. 【转】Git使用教程之远程仓库

    1.远程仓库 在了解之前,先注册github账号,由于你的本地Git仓库和github仓库之间的传输是通过SSH加密的,所以需要一点设置: 第一步:创建SSH Key.在用户主目录下,看看有没有.ss ...

  10. Ansible配置执行远程主机的ssh端口号

    在线上的环境中,服务端的ssh会有进行变更的情况 例如:有些服务器的ssh端口号是 34567 等情况,那么该如何配置呢? 编辑 /etc/ansible/hosts [servers] 配置完毕后, ...