文章目录
一、题目简介
给定一个二叉树,判断其是否是二叉搜索树(Binary Search Tree, BST) 。
一个有效的 BST 满足以下条件:
- 节点的左子树只包含 小于该节点值的节点;
- 节点的右子树只包含 大于该节点值的节点;
- 所有左、右子树也必须是二叉搜索树。
二、题目示例
示例 1:
text
输入:
2
/ \
1 3
输出:true
示例 2:
text
输入:
5
/ \
1 4
/ \
3 6
输出:false
解释:根节点的右子树中包含小于 5 的节点。
三、思路分析(思维导图)
下面是关于「验证二叉搜索树」的思路分析:
验证二叉搜索树
原理
节点必须满足 左 < 根 < 右
所有子树都要满足 BST 性质
解法
递归 + 区间限制
每个节点维护一个[min, max]范围
中序遍历判断升序
BST的中序遍历结果应为严格升序序列
时间复杂度
O(n)
空间复杂度
O(n)
四、解法一:区间限制递归法(Top-Down)
原理说明
我们可以从根节点出发,为每个节点限定一个合法取值区间 [min, max]:
- 根节点的取值范围为整个数值空间
(-∞, +∞); - 对于左子树:节点值必须
< 当前节点值; - 对于右子树:节点值必须
> 当前节点值; - 若当前节点的值不在区间内,则返回
false。
递归逻辑图:
为空
不为空
不在范围内
在范围内
开始
检查节点是否为空
返回 true
判断节点值是否在区间范围内
返回 false
递归左子树 min~节点值
递归右子树 节点值~max
返回左右子树验证结果
Java 代码实现
java
class Solution {
public boolean isValidBST(TreeNode root) {
return helper(root, Long.MIN_VALUE, Long.MAX_VALUE);
}
private boolean helper(TreeNode node, long min, long max) {
if (node == null) return true;
if (node.val <= min || node.val >= max) return false;
return helper(node.left, min, node.val) && helper(node.right, node.val, max);
}
}
时间复杂度
- 每个节点仅被访问一次,因此为 O(n)。
空间复杂度
- 递归层数取决于树的高度,最坏情况下(退化成链表)为 O(n)。
五、解法二:中序遍历法(Bottom-Up)
原理说明
二叉搜索树的中序遍历序列 应该是严格递增的。
我们可以进行一次中序遍历,记录上一个节点值 prev,若当前节点值不大于 prev,则不是 BST。
过程示意图:
右子树 左子树 根节点 右子树 左子树 根节点 中序遍历顺序:左 ->> 根 ->> 右 访问左子树 检查当前节点值是否大于 prev 访问右子树
Java 代码实现
java
class Solution {
long prev = Long.MIN_VALUE;
public boolean isValidBST(TreeNode root) {
if (root == null) return true;
if (!isValidBST(root.left)) return false;
if (root.val <= prev) return false;
prev = root.val;
return isValidBST(root.right);
}
}
时间复杂度
- 一次完整的中序遍历 → O(n)。
空间复杂度
- 递归栈深度与树高有关,最坏情况是 O(n)。
六、两种解法对比
| 解法 | 核心思想 | 优点 | 缺点 | 时间复杂度 | 空间复杂度 |
|---|---|---|---|---|---|
| 区间限制递归 | 通过上下界限制节点取值范围 | 思路清晰,可直接剪枝 | 需传递区间参数 | O(n) | O(n) |
| 中序遍历判断升序 | 利用 BST 的中序性质 | 简洁,可扩展为迭代 | 依赖全局变量记录状态 | O(n) | O(n) |
七、总结
验证二叉搜索树是一个典型的 DFS + 逻辑约束问题,考察的是对树结构的理解与递归控制能力。
- 若倾向于 逻辑自顶向下判断,使用「区间限制法」;
- 若倾向于 性质自底向上验证,使用「中序升序法」。
两种方法都能高效解决该题,需根据个人编程习惯灵活选择。