Leecode98

leecode98 验证二叉搜索树
给定一个二叉树,判断其是否是一个有效的二叉搜索树。
假设一个二叉搜索树具有如下特征:
节点的左子树只包含小于当前节点的数。
节点的右子树只包含大于当前节点的数。
所有左子树和右子树自身必须也是二叉搜索树。
在这里插入图片描述

🔎思路:要知道中序遍历下,输出的二叉搜索树节点的数值是有序序列。(参考leecode题解)

这道题目比较容易陷入两个陷阱:

刚开始我还想使用队列层序遍历这棵树,将结果存入数组,最后判断数组是不是递增(大错特错!)

🌙(1)不能单纯的比较左节点小于中间节点,右节点大于中间节点就完事了。比如下面这棵树:

在这里插入图片描述
按层序遍历,我们得到节点值的数组为 [4, 2, 7, 5, 9]。数组是递增的,但是该树并不是二叉搜索树,因为根节点的右子树中的节点值小于根节点的值。

🌙(2)要解决这道题首先我们要了解二叉搜索树有什么性质可以给我们利用,由题目给出的信息我们可以知道:如果该二叉树的左子树不为空,则左子树上所有节点的值均小于它的根节点的值; 若它的右子树不空,则右子树上所有节点的值均大于它的根节点的值;它的左右子树也为二叉搜索树。
这启示我们设计一个递归函数 helper(root, lower, upper) 来递归判断,函数表示考虑以 root 为根的子树,判断子树中所有节点的值是否都在 (l,r) 的范围内,如果root节点的值val不在(l,r) 范围内,说明不满足条件直接返回,否则我们要继续递归调用检查它的左右子树是否满足,如果都满足才说明这是一棵二叉搜索树。
那么根据二叉搜索树的性质,在递归调用左子树时,我们需要把上界 upper 改为 root.val,即调用 helper(root.left, lower, root.val),因为左子树里所有节点的值均小于它的根节点的值同理递归调用右子树时我们需要把下界 lower 改为 root.val,即调用 helper(root.right, root.val, upper)。函数递归调用的入口为 helper(root, -inf, +inf), inf 表示一个无穷大的值。

🔎代码如下:

class Solution {
    public boolean isValidBST(TreeNode root) {
        return isValidBST(root, Long.MIN_VALUE, Long.MAX_VALUE);
    }

    public boolean isValidBST(TreeNode node, long lower, long upper) {
        if (node == null) {
            return true;
        }
        if (node.val <= lower || node.val >= upper) {
            return false;
        }
        return isValidBST(node.left, lower, node.val) && isValidBST(node.right, node.val, upper);
    }
}
🟢举例:

在这里插入图片描述
首先,我们调用 isValidBST(root, Long.MIN_VALUE, Long.MAX_VALUE),其中 root 是根节点,Long.MIN_VALUE 和 Long.MAX_VALUE 是验证范围的初始最小值和最大值。

步骤 1:
我们进入 isValidBST 方法,传入根节点 4,以及初始的范围 (Long.MIN_VALUE, Long.MAX_VALUE)。

步骤 2:
检查根节点的值 4 是否在 (Long.MIN_VALUE, Long.MAX_VALUE) 的范围内。是的,所以继续。

步骤 3:
递归验证左子树 2。我们进入 isValidBST 方法,传入节点 2,以及范围 (Long.MIN_VALUE, 4)。

步骤 4:
检查节点 2 的值 2 是否在 (Long.MIN_VALUE, 4) 的范围内。是的,所以继续。

步骤 5:
左子树为空,验证通过。

步骤 6:
递归验证右子树 6。我们进入 isValidBST 方法,传入节点 6,以及范围 (4, Long.MAX_VALUE)。

步骤 7:
检查节点 6 的值 6 是否在 (4, Long.MAX_VALUE) 的范围内。是的,所以继续。

步骤 8:
递归验证左子树 5。我们进入 isValidBST 方法,传入节点 5,以及范围 (4, 6)。

步骤 9:
检查节点 5 的值 5 是否在 (4, 6) 的范围内。是的,所以继续。

步骤 10:
左子树为空,验证通过。

步骤 11:
右子树为空,验证通过。

步骤 12:
回到节点 6,递归验证右子树完成。

步骤 13:
回到根节点 4,递归验证右子树完成。

步骤 14:
回到调用 isValidBST 的方法,所有节点验证完成,没有发现违反二叉搜索树条件的节点。

因此,根据给定的代码,这棵二叉树是二叉搜索树。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值