二叉树题解——验证二叉搜索树【LeetCode】前序遍历

98. 验证二叉搜索树

🔍 题目目标

判断一棵二叉树是否为有效的二叉搜索树(BST),定义如下:

  • 左子树所有节点 < 根节点

  • 右子树所有节点 > 根节点

  • 且左右子树也必须是二叉搜索树


一、算法逻辑(逐步通顺讲解每一步思路)

该算法使用了递归 + 上下界限制法,即为每个节点维护一个值域区间 [left, right],确保节点值在区间内才是有效的 BST。

✅ 1️⃣ 初始调用:
从根节点 root 开始判断,默认左右边界为负无穷和正无穷,即 (-inf, +inf)。表示当前节点理论上可以是任意值。

✅ 2️⃣ 递归边界判断:
如果当前节点为 None,说明是空树或到达叶子节点,属于有效 BST,返回 True

✅ 3️⃣ 当前节点合法性判断:
获取当前节点值 x = root.val,判断其是否满足。

即节点值必须严格在当前区间范围内。

✅ 4️⃣ 递归判断左右子树:

  • 左子树的合法区间更新为 (left, x),即值必须 < 当前节点值;

  • 右子树的合法区间更新为 (x, right),即值必须 > 当前节点值;

  • 两者都必须返回 True,整个树才合法。

✅ 5️⃣ 使用逻辑与 and 串联判断:
只有当前节点合法 左右子树也为 BST,整体才能返回 True


二、核心点总结

该算法的核心是:

递归地对每个节点维护上下边界区间 [left, right],判断其值是否符合 BST 的定义,并递归验证左右子树。

✅ 采用“值域约束”方式,严格验证 BST 的定义
✅ 上下界会随着递归深入而收紧,更精确限制节点取值
✅ 非常适合处理“全局性条件”的验证场景,如 BST 中的跨层约束
✅ 简洁高效,是判断 BST 有效性的经典做法

class Solution:def isValidBST(self, root: Optional[TreeNode], left=-inf, right=inf) -> bool:if root is None:return True# x = root.valreturn left < root.val < right and \self.isValidBST(root.left, left, root.val) and \self.isValidBST(root.right, root.val, right)

三、时间复杂度分析

  • 每个节点仅访问一次;

  • 每次访问包含常数操作和两次递归调用。

因此,时间复杂度为:

O(n),其中 n 是二叉树中的节点数


四、空间复杂度分析

空间主要来自递归栈深度

  • 最坏情况是退化成链表时递归深度为 n

  • 最好情况(平衡树)递归深度为 log n

因此空间复杂度为:

O(h),其中 h 是树的高度,最坏情况下为 O(n),平均为 O(log n)


✅ 总结一句话

本算法通过上下界约束方式递归判断每个节点是否符合 BST 条件,时间复杂度 O(n),空间复杂度 O(h),是判断有效二叉搜索树的最经典、最推荐方案之一。

非常好,这里我们就结合输入用例:

root = [5,1,4,null,null,3,6]

用例讲解

root = [5,1,4,null,null,3,6]

来详细还原这段递归算法每一步的过程,帮你彻底理解 isValidBST(root, left, right) 的行为。包括每一步的参数、判断条件、递归路径,以及在什么情况下返回 TrueFalse


🔧 准备工作:还原树结构

先把这个数组构造的二叉树结构还原出来(按 LeetCode 层序规则):

        5/ \1   4/ \3   6

我们希望判断这个树是否是合法的 BST。


🧠 递归过程逐步模拟(输入:[5,1,4,null,null,3,6])

我们从根节点 5 开始调用:


✅ Step 1:isValidBST(5, -inf, +inf)

  • 当前节点值:5

  • 是否满足范围:-inf < 5 < +inf

  • 继续检查左右子树:

→ Step 1.1:isValidBST(1, -inf, 5)(左子树)
  • 当前值:1

  • 范围:-inf < 1 < 5

  • 继续递归左右:

→ Step 1.1.1:isValidBST(None, -inf, 1) → 空树 ✅
→ Step 1.1.2:isValidBST(None, 1, 5) → 空树 ✅

↩️ 1 的子树都合法 → 返回 True


→ Step 1.2:isValidBST(4, 5, +inf)(右子树)
  • 当前值:4

  • 范围:5 < 4 < +inf不合法!

↩️ 4 不在合法范围内,直接返回 False!

此处是整个递归“剪枝”发生的位置

⛔ 说明什么?说明你不能只看当前节点的左右是否比自己小或大,还要满足“整个路径”上的上下界限制(即必须大于所有祖先节点中要求大的那一边)。


❌ 最终结果:返回 False

因为右子树 4 违反了 BST 的约束条件(其值 < 根节点 5,却出现在右子树),因此整个树不是有效的 BST。


📌 小结:每次递归都做了什么?

步骤当前节点left boundright bound判断是否合法结果
15-∞+∞-∞ < 5 < ∞ ✅继续
1.11-∞5-∞ < 1 < 5 ✅继续
1.1.1None-∞1空节点 ✅True
1.1.2None15空节点 ✅True
1.245+∞❌ 4 < 5False

✅ 总结一句话

这套递归结构的关键是:每个节点必须严格落在“它所能合法存在的值域区间”内,这个区间来自于祖先节点不断递归传下来的上下界。

一旦有节点违反这个区间,即可剪枝终止。

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

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

相关文章

Javaweb - 10.3 Servlet 生命周期

目录 生命周期简介 生命周期测试 load-on-startup 补充&#xff1a;defaultServlet Servlet 的继承结构 1. 顶级的 Servlet 接口 2. 抽线的类 GenericServlet 3. HttpServlet 抽象类 4. 自定义 Servlet 补充&#xff1a; 完&#xff01; 生命周期简介 什么是生命周…

RSA数字签名方案的C语言实现(带测试)

RSA 算法的 C语言实现通常比较复杂&#xff0c;但已经有许多密码算法库实现了 RSA 算法&#xff0c;例如OpenSSL、Libgcrypt​ 和 Botan ​等。我们可以在这些库的基础上进行配置或移植&#xff0c;从而快速实现密码算法。但这些库主要面向大量设备进行优化&#xff0c;如通用计…

创客匠人视角:知识变现与创始人 IP 打造的破局之道

当知识付费从流量红利期进入精耕细作阶段&#xff0c;为何专业能力强的内容创作者反而难以变现&#xff1f;创客匠人通过 1500 案例陪跑发现&#xff1a;缺乏 IP 思维的知识输出如同雾中航行&#xff0c;而创始人 IP 打造正是连接知识价值与商业变现的核心桥梁。一、定位重构&…

结构分析设计软件 SCIA Engineer 25.0 x64

详情 Nemetschek SCIA Engineer是一家从事多项目编程、分析和软件设计的公司。该软件具有广泛的不同功能。该软件可用于以简单的方式设计建筑物、工业工厂和桥梁。 Nemetschek SCIA Engineer软件的特点和功能&#xff1a; BIM模型人 使用网格和故事 3D风 自由负载 互联网…

怎么处理[TOO_MANY_REQUESTS/12/disk usage exceeded flood-stage watermark

这个错误说明 Elasticsearch 的磁盘空间严重不足&#xff0c;已触及最高级别&#xff08;flood-stage&#xff09;的水位线。作为自我保护机制&#xff0c;Elasticsearch ​自动将受影响的索引设置为只读模式 (read-only-allow-delete)​&#xff0c;从而阻止写入操作&#xff…

pytorch学习-11卷积神经网络(高级篇)

2.线性模型 3.梯度下降算法 4.反向传播(用pytorch算梯度) 5.用pytorch实现线性回归 6.logistic回归 7.处理多维特征的输入 8.加载数据集 9.多分类问题 10.卷积神经网络(基础篇) 11.卷积神经网络&#xff08;高级篇&#xff09;_哔哩哔哩_bilibili 11.1 GoogleNet Google…

ubuntu 安装QT

在 Ubuntu 系统上安装 Qt 可以通过以下步骤完成&#xff0c;以下是详细的安装指南 &#xff1a; 1. 安装前的准备工作 在开始安装 Qt 之前&#xff0c;需要确保你的 Ubuntu 系统已经更新到最新版本&#xff0c;并且安装了一些必要的依赖。 1.1 更新系统 首先&#xff0c;打…

CppCon 2018 学习:RAPID PROTOTYPING OF GRAPHICS SHADERS IN

这段内容在讲**着色器&#xff08;Shader&#xff09;**的基础概念&#xff0c;尤其是它在现代 GPU&#xff08;图形处理单元&#xff09;中的作用。以下是逐条解释与理解&#xff1a; “Depicting depth perception in 3D models or illustrations by varying levels of darkn…

Angular v20版本正式发布

过去几年对 Angular 来说很具变革性,我们推出了像 Signals 这样的反应性功能和 Zoneless 应用的强大能力。我们希望这些功能可以帮助 Angular 社区构建下一代的 Web 应用,实现快速上市和强大的性能。 我们的旅程才刚刚开始!Angular v20 是最新的发布版本,我们花费了无数个小…

Oracle如何使用序列 Oracle序列使用教程

Oracle序列&#xff08;sequence&#xff09;是一种数据库项&#xff0c;能够生成一个整数序列。通常用于填充数字类型的主键列。 Oracle序列 Oracle序列使用教程&#xff1a; 1、创建序列&#xff1a; CREATE SEQUENCE sequence_name[START WITH start_num][INCREMENT BY incr…

深入探索 Vanna:让数据库交互更智能

深入探索 Vanna&#xff1a;让数据库交互更智能 在数字化时代&#xff0c;与数据库进行高效交互是许多开发者、数据分析师和企业面临的挑战。传统的 SQL 查询编写不仅需要对数据库结构有深入的了解&#xff0c;还需要花费大量的时间和精力来调试和优化。Vanna&#xff0c;一个…

C#上位机之网口通信与协议!

文章目录前言一、网口通信概念二、使用网口通信准备三、使用步骤前言 C#上位机之网口通信与协议&#xff01; 一、网口通信概念 定义 &#xff1a;Socket 可以理解为一个通信端点&#xff0c;它提供了应用程序与网络之间的接口&#xff0c;使得应用程序能够在网络上发送和接收…

Android Studio 创建类时如何自动添加类注释

打开IDEA或AS&#xff0c;点击菜单栏File——Settings——Editor——File and Code Templates。 点击右边Tab页的Includes&#xff0c;选择File Header&#xff0c;修改类头模版&#xff0c;如图&#xff1a; 记得选中Project&#xff0c;否则默认是整个AS都会进行设置

C++11:shared_ptr的设计哲学(原理+源码):内存安全和性能的架构权衡

0.简介 在C编程世界中&#xff0c;内存管理是一把双刃剑&#xff0c;手动管理带来了极致的内存控制能力&#xff0c;但也带来了像内存泄漏&#xff0c;野指针等问题&#xff1b;自动垃圾回收虽然安全&#xff0c;但却会带来一定的性能损耗。本文将介绍C11引入shared_ptr&#…

Mysql EXPLAIN 执行计划

EXPLAIN SELECT SQl。。。。界面filtered储引擎返回的数据在经过服务器层 WHERE 条件过滤后&#xff0c;剩余数据占总行数的百分比估计值rows * filtered/100 越接近100%效率越高rowspossible_keys 可能选择的索引key最终决定选择的行partitions问了哪些分区select_type查询…

力扣刷题记录【1】146.LRU缓存

前言&#xff1a; 请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。 实现 LRUCache 类&#xff1a; LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存int get(int key) 如果关键字 key 存在于缓存中&#xff0c;则返回关键字的值&…

西门子S7-1200 PLC主流通信方法及应用

一、通信基础 1. 网络术语与设备 - 关键设备&#xff1a;交换机、路由器、网关等。 - 物理接口&#xff1a;RS-485&#xff08;支持多点通信&#xff09;、RS-232C&#xff08;点对点串行通信&#xff09;。 2. OSI参考模型 - 核心框架&#xff1a;理解协议分层&…

MySQL实现任意级子目录的主要方案以及区别

常见的实现方案及区别 1. 邻接表&#xff08;Adjacency List&#xff09; 方案描述&#xff1a; 每条记录存储一个节点的父节点ID。 表结构大致&#xff1a; id INT PRIMARY KEY, name VARCHAR(...), parent_id INT -- 指向父节点的ID&#xff0c;根节点为NULL或0优点&…

Linux网络socket套接字(完)(5)

文章目录前言一、多进程版的Tcp网络程序捕捉SIGCHLD信号让孙子进程提供服务二、多线程版的Tcp网络程序三、线程池版的Tcp网络程序四、Tcp协议通讯流程通讯流程总览三次握手的过程数据传输的过程四次挥手的过程总结前言 结束喽&#xff0c;至少这个Tcp套接字有关内容要结束了~  …

Web3 Study Log 003

Web3 Study Log 003 2025-7-5 这几天各种各样的琐事&#xff0c;处理完了&#xff0c;真的烦&#xff0c;估计能消停一段时间了… 今天终于能够坐下来好好学习&#xff0c;今天学习了chainlink的使用&#xff0c;能够获取 ETH/USD 实时价格&#xff0c;然后写了一个简单的众…