98. 验证二叉搜索树(中等)

Blind 75 › 98. 验证二叉搜索树(中等) (第 7 章)
文章工具

题目

给一棵二叉树的根节点 root,判断它是不是一棵合法的二叉搜索树(BST)。合法需要同时满足三点:

  1. 左子树中所有节点的值都严格小于当前节点的值;
  2. 右子树中所有节点的值都严格大于当前节点的值;
  3. 左、右子树本身也必须各自是一棵合法的 BST。

自造非法示例:层序数组 [10,5,15,null,null,6,20] 应返回 false。单看 15 的左孩子 6,确实满足 6 < 15;但 6 位于根节点 10 的右子树中,必须大于 10,实际却小于 10,因此整棵树不合法。

自造合法示例:层序数组 [4,2,6,1,3,5,7] 应返回 true——每个节点都落在它所有祖先逐步划定的允许范围内。

约束:节点数 1 ~ 104;节点值在 32 位有符号整数范围内;树节点结构见下文代码。

思路

一句话:BST 的“合法”不是父子之间的局部比较,而是每个节点都要满足所有祖先留下的全局约束。

先想最直白的做法:对每个节点只检查 左孩子 < 自己 < 右孩子。它为什么不够?因为它只看一层父子关系,管不住更上面的祖先。前面 [10,5,15,null,null,6,20] 的例子就说明了这一点:6 比父亲 15 小,却违反了“必须大于祖先 10”的约束。

更严格但笨的做法是:对每个节点都去扫一遍它的左子树,确认所有值都小于它;再扫一遍右子树,确认所有值都大于它。这样每个节点可能被多个祖先重复检查,总代价会到 O(n²),明显不划算。

关键观察:BST 的合法性有两条等价刻画:

  • 中序遍历严格递增。 按「左 → 根 → 右」访问 BST,得到的值序列必然从小到大排列;反过来,如果中序序列严格递增,那么这棵树也一定是 BST。
  • 每个节点都有一个允许值区间。 从根开始,根的可取范围是 (-∞, +∞);往左走时,父节点的值成为新的上界;往右走时,父节点的值成为新的下界。

两条路都能一次遍历完成。本文主推区间递归:它最贴合题目“左子树全部小于、右子树全部大于”的字面定义,也最好记。

解法

定义辅助函数 valid(node, low, high),表示判断以 node 为根的子树是否完全落在开区间 (low, high) 内:

  1. 若 node 为空,返回 true,空树视为合法。
  2. 若 node.val 不满足 low < node.val < high,返回 false。
  3. 递归检查左子树,上界收紧为当前值:valid(node.left, low, node.val)。
  4. 递归检查右子树,下界收紧为当前值:valid(node.right, node.val, high)。
  5. 左右都合法,整棵子树才合法;根节点入口调用 valid(root, -∞, +∞)。

以合法树 [4,2,6,1,3,5,7] 为例,区间从根向下逐渐收紧:

节点允许区间区间怎么来的
4(根)(-∞, +∞)根节点没有祖先约束
2(4 的左孩子)(-∞, 4)进入左子树,父节点值变上界
1(2 的左孩子)(-∞, 2)继续往左,上界继续收紧
3(2 的右孩子)(2, 4)从 2 往右,下界为 2,上界仍为 4
6(4 的右孩子)(4, +∞)进入右子树,父节点值变下界
5(6 的左孩子)(4, 6)从 6 往左,上界收紧为 6
7(6

🔒

本篇为付费内容

您已阅读试读部分,购买后即可解锁全文。

⚠️ 本站内容已做唯一性标记并受版权保护,未经授权禁止转载,侵权必究。

还没有评论,来说两句?

发表评论

欢迎交流技术细节;广告与人身攻击会被删除。

在线咨询