给定一个二叉树,判断它是否是合法的二叉查找树(BST)

一棵BST定义为:

  • 节点的左子树中的值要严格小于该节点的值。
  • 节点的右子树中的值要严格大于该节点的值。
  • 左右子树也必须是二叉查找树。
  • 一个节点的树也是二叉查找树。
您在真实的面试中是否遇到过这个题?

Yes
样例

一个例子:

  2
/ \
1 4
/ \
3 5

上述这棵二叉树序列化为 {2,1,4,#,#,3,5}.

思路:

最初解法(错误解法):

使用递归的方式,按照二叉搜索树的定义去判断。考虑各种情况,然后递归。但是这种方法,一开始有漏洞,只能通过87%。
发现问题所在:像是{10,5,15,#,#,6,20}这种实例不能通过,经过考虑,确实存在问题。

/**
* Definition of TreeNode:
* class TreeNode {
* public:
* int val;
* TreeNode *left, *right;
* TreeNode(int val) {
* this->val = val;
* this->left = this->right = NULL;
* }
* }
*/
class Solution {
public:
/**
* @param root: The root of binary tree.
* @return: True if the binary tree is BST, or false
*/ /*
思路:使用递归的方式,按照二叉搜索树的定义去判断。考虑各种情况,然后递归。
但是这种方法,一开始有漏洞,只能通过87%。
发现问题所在:像是{10,5,15,#,#,6,20}这种实例不能通过,经过考虑,确实存在问题。 */
bool isValidBST(TreeNode *root) {
// write your code here if(root==NULL){
return true;
} if(root->left==NULL&&root->right==NULL){
return true;
} if(root->left!=NULL&&root->right==NULL){
if(root->left->val<root->val){
return isValidBST(root->left);
}
else{
return false;
}
} if(root->right!=NULL&&root->left==NULL){
if(root->right->val>root->val){
return isValidBST(root->right);
}
else{
return false;
}
} if(root->left!=NULL&&root->right!=NULL){
if(root->val<root->right->val&&root->val>root->left->val){
return isValidBST(root->left)&&isValidBST(root->right);
}
else{
return false;
}
}
}
};

解决方法1:借助辅助空间,因为中序遍历一定是有序的。

/
* Definition of TreeNode:
* class TreeNode {
* public:
* int val;
* TreeNode left, right;
* TreeNode(int val) {
* this->val = val;
* this->left = this->right = NULL;
* }
* }
*/
class Solution {
public:
/
* @param root: The root of binary tree.
* @return: True if the binary tree is BST, or false
*/ /*
解决方法1:借助辅助空间,因为中序遍历一定是有序的。
*/
void help(vector<int> &vec,TreeNode *root){
//使用中序遍历,将元素压入容器;
if(root==NULL)
return ;
help(vec,root->left);
vec.push_back(root->val);
help(vec,root->right);
}
bool isValidBST(TreeNode *root) {
if(root==NULL)
return true;
vector<int> vec;
help(vec,root); int last=vec[0];
vec.erase(vec.begin());
for(auto e:vec){
if(last>=e)
return false;
last=e;
}
return true;
}

解决方法2:prev指针记录前一个节点,省下了辅助空间,而且要注意prev传进去还应该是引用。方法很好!

/**
* Definition of TreeNode:
* class TreeNode {
* public:
* int val;
* TreeNode *left, *right;
* TreeNode(int val) {
* this->val = val;
* this->left = this->right = NULL;
* }
* }
*/
class Solution {
public:
/**
* @param root: The root of binary tree.
* @return: True if the binary tree is BST, or false
*/ /* 解决方法2:prev指针记录前一个节点,省下了辅助空间,而且要注意prev传进去还应该是引用。 */ bool isValidBST(TreeNode* root)
{
TreeNode *pre = NULL;
return validate(root, pre);
} bool validate(TreeNode *root, TreeNode *&pre)
{
if (root == NULL)
return true;
if (!validate(root->left, pre))
return false;
if (pre != NULL && pre->val >= root->val)// 如果当前还是NULL那就先不管吧,继续往下运行。
return false;
pre = root;
return validate(root->right, pre);
}
};

Lintcode---验证二叉查找树的更多相关文章

  1. Java for LintCode 验证二叉查找树

    给定一个二叉树,判断它是否是合法的二叉查找树(BST) 一棵BST定义为: 节点的左子树中的值要严格小于该节点的值.    节点的右子树中的值要严格大于该节点的值.    左右子树也必须是二叉查找树. ...

  2. 验证二叉查找树(LintCode)

    验证二叉查找树 给定一个二叉树,判断它是否是合法的二叉查找树(BST) 一棵BST定义为: 节点的左子树中的值要严格小于该节点的值. 节点的右子树中的值要严格大于该节点的值. 左右子树也必须是二叉查找 ...

  3. lintcode:验证二叉查找树

    题目 给定一个二叉树,判断它是否是合法的二叉查找树(BST) 一棵BST定义为: 节点的左子树中的值要严格小于该节点的值. 节点的右子树中的值要严格大于该节点的值. 左右子树也必须是二叉查找树. 一个 ...

  4. LintCode 11 二叉查找树的搜索区间

    题目链接:http://www.lintcode.com/zh-cn/problem/search-range-in-binary-search-tree/ 1.描述 给定两个值 k1 和 k2(k1 ...

  5. lintcode:在二叉查找树中插入节点

    题目:  在二叉查找树中插入节点 给定一棵二叉查找树和一个新的树节点,将节点插入到树中. 你需要保证该树仍然是一棵二叉查找树.  样例 给出如下一棵二叉查找树,在插入节点6之后这棵二叉查找树可以是这样 ...

  6. 验证二叉查找树 · Validate Binary Search Tree

    [抄题]: [思维问题]: 不知道要定义resultType, 其实用仔细分析判断条件就行了:是否是bst+最大最小值 类似于平衡二叉树:是否平衡+左右的高度差 [一句话思路]: [输入量]:空: 正 ...

  7. (lintcode全部题目解答之)九章算法之算法班题目全解(附容易犯的错误)

    --------------------------------------------------------------- 本文使用方法:所有题目,只需要把标题输入lintcode就能找到.主要是 ...

  8. CSDN总结的面试中的十大算法

    1.String/Array/Matrix 在Java中,String是一个包含char数组和其它字段.方法的类.如果没有IDE自动完成代码,下面这个方法大家应该记住: toCharArray() / ...

  9. 算法——dfs 判断是否为BST

    95. 验证二叉查找树 中文English 给定一个二叉树,判断它是否是合法的二叉查找树(BST) 一棵BST定义为: 节点的左子树中的值要严格小于该节点的值. 节点的右子树中的值要严格大于该节点的值 ...

  10. Lintcode 85. 在二叉查找树中插入节点

    -------------------------------------------- AC代码: /** * Definition of TreeNode: * public class Tree ...

随机推荐

  1. express路由和中间件

    路由 简单来说,express路由就是用来处理一些请求,响应一些url地址. var express = require('express'); var app = express(); app.ge ...

  2. linux shell 自定义函数(定义、返回值、变量作用域)介绍

    linux shell 可以用户定义函数,然后在shell脚本中可以随便调用.下面说说它的定义方法,以及调用需要注意那些事项. 一.定义shell函数(define function) 语法: [ f ...

  3. jvm分析内存泄露

          首页 所有文章 资讯 Web 架构 基础技术 书籍 教程 Java小组 工具资源 - 导航条 - 首页 所有文章 资讯 Web 架构 基础技术 书籍 教程 Java小组 工具资源     ...

  4. 面试DB优化

    高频全表扫描 0.5 表大小超过200M,且SQL高频执行(15分钟内超过500次),PIR 3级,表大小超过高速缓存的1.5%,报PIR 2级. 禁止使用select * 0.5 禁止使用selec ...

  5. acle联机日志文件的维护

    1.刷新重做日志缓存的时机 a.commit b.缓存满了 c.checkpoint,checkpoint的触发有两种机制: 定时触发,由log_checkpoint_interval[1]参数决定间 ...

  6. 流畅的python第十一章接口学习记录

    鸭子协议(忽略对象真正类型,转而关注对象有没有实现所需的方法,签名和语义) 标准库中的抽象基类 collections.abc模块中的抽象基类 抽象方法是抽象基类中用来强制子类必须实现的方法,如果子类 ...

  7. :视频播放器与Handler 完美调用

    Handler之消息循环   Handler是用于操作线程内部的消息队列的类.这有点绕,没关系,我们慢慢的来讲.前面Looper一篇讲到了Looper是用于给线程创建消息队列用的,也就是说Looper ...

  8. ubuntu 不是 识别 android 设备 解决方法

    ubuntu: 在终端输入lsusb: langu@langu:~$ lsusb Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root ...

  9. Echarts 获取后台数据 使用后台数据展示 柱形图

    后台数据要以json格式返回 页面:引用echarts.js , 然后data以ajax的数据请求并返回 <%@ page language="java" import=&q ...

  10. 疯狂java学习路线图