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

Assume a BST is defined as follows:

  • The left subtree of a node contains only nodes with keys less than the node's key.
  • The right subtree of a node contains only nodes with keys greater than the node's key.
  • Both the left and right subtrees must also be binary search trees.

这是easy题么=_= 被虐得好惨,开始想得简单,不就是验证BST咩,递归的话只用判断左右孩子是不是BST就行了。。。这就错了,孩子是BST并不能保证整颗树就是BST啊。比如下图

              5

              /    \

             3     6

             /   \  /  \

           1   8 4  7

5的左右孩子都分别是合法的BST,但是整颗树却不是,因为6的左孩子比5小;3的右孩子比5大。

所以在递归检测的时候,不仅仅要保证当前的树是BST,也要保证当前的树不破坏原有的BST结构,怎么办呢?

认真思考BST的结构性质会发现,BST就好像把一串数字做了很多切分,一部分放左变一部分放右边,一直这样递归的切下去。而这个切法可不是乱切,他是永远保持 “小的放左边,大的放右边” 的,这样切就有个性质,就是被切出来的每一段区域,都有严格的上下界。

              3

              /    \

             1     5

             /   \  /  \

           0   2 4  6

上图是一颗合法的BST,如果我们将其按照中序遍历方式展开可得:0 1 2 3 4 5 6

注意观察1,3,5 把序列切分成了4个区域,每个区域有一个数子分别是0,2,4,6。除了0没有下界,6没有上界以外,2和4都有明确的上下界。

所以在递归检测当中,我们应该同时传递上下界信息。

思路:在递归检测左右孩子的同时传递上下界信息,在递归调过程中更新上下界信息。

举个栗子:以上图为例,以根节点启动算法时,上下界信息为空,在检测1,3,5这个结构是否为合法BST后,递归的检测根节点为1的树(左孩子)并传入上界信息3;同样,递归检测根节点为5的树(右孩子)并传入下界信息3...

在递归过程中更新上下界信息,比如在检测到2这个节点的时候,更新了下界为1,而上界不用更新还是3。

bool validIter(TreeNode *node, TreeNode *left, TreeNode *right) {
if (!node) return true;
bool validLeft = true;
bool validRight = true;
if (node->left) {
validLeft = (node->val > node->left->val);
if (left) {
validLeft = validLeft && (node->left->val > left->val);
}
} if (node->right) {
validRight = (node->val < node->right->val);
if (right) {
validRight = validRight && (node->right->val < right->val);
}
} if (validLeft && validRight) {
return validIter(node->left, left, node) && validIter(node->right, node, right);
}
return false;
} bool isValidBST(TreeNode *root) {
return validIter(root, NULL, NULL);
}

要点:检测当前树是否为BST的时候还要检测是否违反了上下界的约束。

解法二:使用中序便利

上面的递归解法不太好想,我跌跌撞撞的提交了两次才对算法有了较深的理解。前面也说到,BST按照中序便利的话将会产生一个有序的序列,这是BST的性质。那为何不利用这个性质:先中序遍历产生数组,然后检查数组是否有序和是否有重复。

这个思路就是这么简单。。。中序遍历然后检查数组,所以才是easy题啊 (逃

void midOrderTraversal(TreeNode *node, vector<int> &s) {
if (!node) return;
midOrderTraversal(node->left, s);
s.push_back(node->val);
midOrderTraversal(node->right, s);
} bool isValidBST(TreeNode *root) {
if (!root) return true;
vector<int> s;
midOrderTraversal(root, s); for (int i = ; i < s.size(); i++) {
if (s[i] < s[i-] || s[i] == s[i-]) {
return false;
}
}
return true;
}

[LeetCode] Validate Binary Search Tree (两种解法)的更多相关文章

  1. LeetCode: Validate Binary Search Tree 解题报告

    Validate Binary Search Tree Given a binary tree, determine if it is a valid binary search tree (BST) ...

  2. [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 ...

  3. 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 ...

  4. LeetCode: Validate Binary Search Tree [098]

    [题目] Given a binary tree, determine if it is a valid binary search tree (BST). Assume a BST is defin ...

  5. LeetCode :: Validate Binary Search Tree[具体分析]

    Assume a BST is defined as follows: The left subtree of a node contains only nodes with keys less th ...

  6. [leetcode]Validate Binary Search Tree @ Python

    原题地址:https://oj.leetcode.com/problems/validate-binary-search-tree/ 题意:检测一颗二叉树是否是二叉查找树. 解题思路:看到二叉树我们首 ...

  7. Leetcode 笔记 98 - Validate Binary Search Tree

    题目链接:Validate Binary Search Tree | LeetCode OJ Given a binary tree, determine if it is a valid binar ...

  8. 【LeetCode练习题】Validate Binary Search Tree

    Validate Binary Search Tree Given a binary tree, determine if it is a valid binary search tree (BST) ...

  9. 【leetcode】Validate Binary Search Tree

    Validate Binary Search Tree Given a binary tree, determine if it is a valid binary search tree (BST) ...

随机推荐

  1. SNMP报文抓取与分析(一)

    SNMP报文抓取与分析(一) 1.抓取SNMP报文 SNMP报文的形式大致如下图所示 我们这里使用netcat这个工具来抓取snmp的PDU(协议数据单元).(因为我们并不需要前面的IP和UDP首部) ...

  2. 一个iOS 框架介绍:MKNetworkKit

    http://blog.csdn.net/kmyhy/article/details/12276287 http://blog.csdn.net/mobailwang/article/details/ ...

  3. effective c++ resources

    http://www.cnblogs.com/littlethank/archive/2011/12/15/2288787.html http://www.cnblogs.com/liao-xiao- ...

  4. ffmpeg-20160617-git-bin.7z ffmpeg-20160626-git-bin.7z

    ESC 退出 0 进度条开关 1 屏幕原始大小 2 屏幕1/2大小 3 屏幕1/3大小 4 屏幕1/4大小 S 下一帧 [ -2秒 ] +2秒 ; -1秒 ' +1秒 下一个帧 -> -5秒 f ...

  5. nyoj116_士兵杀敌(二)_树状数组

    士兵杀敌(二) 时间限制:1000 ms  |  内存限制:65535 KB 难度:5   描述 南将军手下有N个士兵,分别编号1到N,这些士兵的杀敌数都是已知的. 小工是南将军手下的军师,南将军经常 ...

  6. C++基础(纯虚函数与抽象类)

    C++基础之纯虚函数与抽象类 引言 纯虚函数在C++编程中的地位很重要,其关联到了设计模式中"接口"的概念. 语法 纯虚函数的语法: 1.  将成员函数声明为virtual 2.  ...

  7. 【leetcode】Single Number (Medium) ☆

    题目: Given an array of integers, every element appears twice except for one. Find that single one. No ...

  8. 如何获得images.xcassets 中图片的路径?

    UIImage加载图片的方式以及Images.xcassets对于加载方法的影响 重点: Images.xcassets中的图片资源只能通过imageNamed:方法加载,通过NSBundle的pat ...

  9. 甲鱼od19篇随笔

    在一个程序里会有多个对话框,这时要准确的判断要找的对话框就比较困难了所以这里就需要借助 1:Resource Hacker工具来准确的定位涉及到的对话框 2:在od中查找指令,然后在所有找到的指令上下 ...

  10. Java异常题库

    一.填空题 __异常处理__机制是一种非常有用的辅助性程序设计方法.采用这种方法可以使得在程序设计时将程序的正常流程与错误处理分开,有利于代码的编写和维护. 在Java异常处理中可以使用多个catch ...