验证搜索二叉树

目录

题目

方法一

思路

优化

方法二

思维误区

递归关系推导

代码实现


题目

98. 验证二叉搜索树       

难度:中等

给你一个二叉树的根节点root ,判断其是否是一个有效的二叉搜索树。

有效 二叉搜索树定义如下:

  • 节点的左子树只包含 小于 当前节点的数。
  • 节点的右子树只包含 大于 当前节点的数。
  • 所有左子树和右子树自身必须也是二叉搜索树。

示例 1:

 

 输入:root = [2,1,3]

 输出:true

示例 2: 

输入:root = [5,1,4,null,null,3,6] 

输出:false

解释:根节点的值是 5 ,但是右子节点的值是 4 。 

方法一

思路

我们知道一个二叉搜索树的中序遍历得到的序列一定是升序的。那么我们直接中序遍历二叉树,将每个结点的值保存,然后判断得到的序列是否升序即可。这种方法的时间复杂度和空间复杂度均为O(n)。

Q:为什么中序遍历一颗二叉树得到升序序列可以证明这颗树是二叉搜索树?

A:二叉搜索树的定义是:对于树中的每个节点,它的左子树中的所有节点的值都小于该节点的值,而它的右子树中的所有节点的值都大于该节点的值。这个特性保证了二叉搜索树在结构上有序。而中序遍历二叉树的顺序是:先遍历左子树,然后访问根节点,最后遍历右子树。由于二叉搜索树的左子树节点值小于根节点,右子树节点值大于根节点,因此中序遍历二叉搜索树的结果会是一个升序序列。反过来,如果中序遍历一颗二叉树得到的是升序序列,那么这颗树的每个节点的左子树节点值都小于它,右子树节点值都大于它,这符合二叉搜索树的定义。

A:当访问任意节点A时,肯定已经先访问了A的左子树,因为得到的是升序序列,此时A的值大于左子树所有的值,A和左子树满足二叉搜索树的定义,同理A和右子树满足二叉搜索树的定义,所以以A为根节点数是二叉搜索树。所以这颗树满足二叉搜索树的定义,是一颗二叉搜索树。

优化

这个算法还可进一步优化,判断输出序列是否升序仅需检查当前节点的值是否大于前一个中序遍历到的节点的值即可。所以我们仅需保存上一个结点的值即可。这种方法的时间复杂度为O(n),时间复杂度均为O(1) (忽略函数调用栈空间)。

这种方法很容易想到,实现也很容易,在此我们不具体实现。如果大家对二叉树的遍历不熟悉,可以参考我的往期博客:二叉树的遍历。

方法二

思维误区

通过搜索二叉树的性质:对于树中的每个节点,它的左子节点值小于该节点的值,而它的右子节点的值大于该节点的值。我们很容易想出一个递归算法,即递归判断每个结点的左子结点和右子结点,判断他们是否小于或大于父节点的值。如果所有结点都符合条件,则该树为二叉搜索树。

其实这是一个经典的思维误区,我们举一个反例:

对于这颗树它的树中的每个节点,它的左子节点值小于父节点的值,而它的右子节点的值大于该节点的值。但他并不是一个二叉搜索树。

为什么呢?因为二叉搜索树定义中

  • 节点的左子树只包含 小于 当前节点的数。
  • 节点的右子树只包含 大于 当前节点的数。

 也就是说每个结点的左子节点的上界为当前节点,右子节点的下界为当前节点。同时他们还需要有一个下界/上界,保证他们符合二叉搜素树的定义。

那么我们现在只要知道左子节点的下界,右子节点的上界。就可以得出递归关系,进行递归判断。

递归关系推导

对于二叉树中的结点(除根节点,与其左右结点)都可概括为以下四种类型:

我们先分析C作为B左子树的两种情况:

情况一:

 情况二:

上界:对于这两种情况 ,C 都要小于 B ,即 C 的上界为 B。

下界:情况一下,C 的下界为负无穷。B的下届也为负无穷。即 C 的下界为 B 的下界。情况二下,C 必须小于 A,即 C的下界为A。B的下界也为A, 即 C 的下界为 B 的下界.

综上可得:当前结点的左子节点的上界为当前节点,下界为当前节点的下界。

C作为B右子树的两种情况:

情况一:

情况二:

上界: 情况一下,C 的上界为正无穷。B的上界届也为正无穷。即 C 的上界为 B 的上界。情况二下,C 必须小于A,即 C的上界为A。B的上界也为A, 即 C 的上界为 B 的上界.

下界:对于这两种情况 ,C 都要大于 B ,即 C 的下界为 B。

 综上可得:当前结点的右子节点的下界为当前节点,上界为当前节点的上界。

代码实现

现在我们得到了递归关系,只需递归判断左右子树即可。

代码如下:

class Solution {
public:bool istrue(TreeNode* root,long long min,long long max){if(!root) return true;if(root->val<=min || root->val>=max){return false;}return istrue(root->left,min,root->val) && istrue(root->right,root->val,max);//[min,root->val] [root->val,max]}bool isValidBST(TreeNode* root) {return istrue(root,LONG_MIN,LONG_MAX);}
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/691506.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

RZ9692实训开发通信系统构建(含配置json配置文件)

实验名称 通信系统的构建 实验目的&#xff1a; 实现一个通信系统的构建&#xff0c;要求传输两路正弦波&#xff0c;和一路视频信号&#xff0c;要求在接受端完整接受正弦信号和视频信号。 一、实验原理&#xff1a; 数字通信系统的一般模型&#xff1a; 数字通信系统的一…

c 双向链表

图片 #include <stdio.h> #include <stdlib.h> #include <string.h>int main(void){ struct film{char name[20];int id;struct film *pre; //前向指针struct film *next; //后向指针 };struct film *headNULL;struct film *ls,*lspre,*work;in…

【HTTP下】总结{重定向/cookie/setsockopt/流操作/访问网页/总结}

文章目录 1.请求头2.cookie理解 3.vim跳转/搜索4.setsockopt被重用的意思 5.流操作5.1定位读取指针5.2ifstram::read() 6.总结6.1 百度搜索框搜索功能字符6.2请求uri请求和响应的第一行都有http版本请求内容里有GET /favicon.ico HTTP/1.1 6.3访问网页Fiddler抓包原理&#xff…

新iPadPro是怎样成为苹果史上最薄产品的|Meta发布AI广告工具全家桶| “碾碎一切”,苹果新广告片引争议|生成式AI,苹果倾巢出动

Remini走红背后&#xff1a;AI生图会是第一个超级应用吗&#xff1f;新iPadPro是怎样成为苹果史上最薄产品的生成式AI&#xff0c;苹果倾巢出动Meta发布AI广告工具全家桶&#xff0c;图像文本一键生成解放打工人苹果新iPadPro出货量或达500万台&#xff0c;成中尺寸OLED发展关键…

docker安装向量数据库milvus

Miluvs Milvus 向量数据库能够帮助用户轻松应对海量非结构化数据(图片 / 视频 / 语音 / 文本)检索。 单节点 Milvus 可以在秒内完成十亿级的向量搜索,分布式架构亦能满足用户的水平扩展需求。 Milvus 向量数据库的应用场景包括:互联网娱乐(图片搜索 / 视频搜索)、新零售…

NX/UG二次开发—3D几何—多边形内部最大圆

多边形内部最大圆&#xff0c;为什么不能说最大内切圆&#xff1f;如果正方形或正凸多边形&#xff0c;最大内部圆是与边相切的&#xff0c;但对于不规则多边形&#xff0c;很多情况是正好经过一些凹点。 本次介绍在NX中计算封闭边界内部最大圆&#xff1a; 1、首先按顺序排序…

前端小程序调用 getLocation 实现地图位置功能,通过 纬度:latitude 经度: longitude 获取当前位置

1、首先登录一下 腾讯的位置服务 有账号就登录没账号就注册&#xff0c; 点击右上角的控制台点击左侧的应用管理 ---> 我的应用 ---->> 创建应用 1、创建应用 2、列表就会显示我们刚刚创建好的 key 3、点击添加 key 4、按照要求填写信息 我们用的是小程序 所以选择…

Ansible主机清单与playbook 剧本

一、inventory 主机清单 Inventory支持对主机进行分组&#xff0c;每个组内可以定义多个主机&#xff0c;每个主机都可以定义在任何一个或多个主机组内。 如果是名称类似的主机&#xff0c;可以使用列表的方式标识各个主机。 vim /etc/ansible/hosts [webservers] 192.168.80.…

Docker停止不了

报错信息 意思是&#xff0c;docker.socket可能也会把docker服务启动起来 解决 检查服务状态 systemctl status dockersystemctl is-enabled docker停止docker.socket systemctl stop docker.socket停止docker systemctl stop docker知识扩展 安装了docker后&#xff0c;…

c++:刷题必备 容器map的使用

文章目录 map的概念map的使用构造![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/30e9a697b50d47a591af6e9ae2bbb7d7.png)insert迭代器遍历 findoperator[]举例 map的概念 map是一个关联容器,里面的每一个位置pair,会存储两个值,一个是key,另一个是value. 我们可以…

双点路由重发布实验

要求&#xff1a;R1的环回并没有宣告进OSPF网络&#xff0c;需要通过重发布导入到OSPF网络。 保证全网可达&#xff0c;且没有路由回馈以及选路不佳。 实验配置&#xff1a; [r1-ospf-1]import-route direct[r1]acl 2000 [r1-acl-basic-2000]rule per source 192.168.12.0 0 …

探索数据结构(让数据结构不再成为幻想)

目录 什么是数据结构 数据与结构 什么是算法 复杂度分析 时间复杂度与空间复杂度 时间复杂度 思考&#xff1a; 空间复杂度 常数阶O(1) 对数阶O(logn) 线性阶O(n) 以下为空间复杂度为O(n) 线性对数阶O(nlogn) 平方阶O(n) 指数阶O(2^n) 什么是数据结构 数据结构…