二叉树题解——验证二叉搜索树【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.val
        return 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

✅ 总结一句话

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值