LeetCode100之验证二叉搜索树(98)--Java

1.问题描述

        给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。

        有效 二叉搜索树定义如下:

  • 节点的左子树只包含 小于 当前节点的数。
  • 节点的右子树只包含 大于 当前节点的数。
  • 所有左子树和右子树自身必须也是二叉搜索树。

        示例1

输入:root = [2,1,3]
输出:true

        示例2 

输入:root = [5,1,4,null,null,3,6]
输出:false
解释:根节点的值是 5 ,但是右子节点的值是 4 。

        提示

  • 树中节点数目范围在[1, 104] 内
  • -231 <= Node.val <= 231 - 1

        难度等级

                中等

        题目链接

                验证二叉搜索树

2.解题思路

        这道验证二叉搜索树的题,如果树的遍历和二叉搜索树概念熟悉的人,可以很快的做出来。我们对二叉搜索树进行中序遍历的话,二叉搜索树中的节点会按照升序输出,也就是从小到大输出。所以我们想要判断它是否是一个二叉搜索树,直接将它中序遍历,判断是否是升序输出即可。

        在升序遍历之前,我们需要定义一个变量来存储已有序列的最大值,也就是当前序列最后遍历出来的那个节点。

    //已经遍历的序列的最大值
    TreeNode max;

        接着,我们要来确定递归结束的逻辑,如果节点为空,那就返回true,这没什么难度。

        //如果节点为空,返回true
        if(root == null){
            return true;
        }

        然后,我们就可以按照中序遍历的模版进行遍历了。

        先递归调用当前方法遍历左子树,判断左子树是否为二叉搜索树,如果不是,直接返回false。

        //左
        boolean left = isValidBST(root.left);
        if(!left){
            return false;
        }

        接着,进行单层递归逻辑的处理。判断已有序列的最大值是否存在,如果存在的话,再判断当前节点的值是否大于已有序列的最大值,如果小于等于已有序列的最大值,那么序列就不是升序的,该二叉树也不是二叉搜索树,直接返回false;如果大于已有序列的最大值,则更新已有序列的最大值。

        //根
        //当前值小于已有序列的最大值,返回false
        if(max != null && root.val <= max.val){
            return false;
        }
        //更新序列的最大值
        max = root;

        最后递归调用当前方法遍历右子树,判断右子树是否为二叉搜索树,并将结果直接返回。

        //右
        boolean right = isValidBST(root.right);
        //返回验证的结果
        return right;

        这里要提一个小坑,是我已经一开始做题踩到的。我们一看到二叉搜索树,很容易就想到根节点大于左节点,小于右节点,然后就直接用这个逻辑来递归判断是不是二叉搜索树了。这种情况下,如果右子树的左子树的值小于当前的根节点的话,但是按照真正的二叉搜索树的定义,右边的节点必须全部大于根节点,所以这种情况是被误判为二叉搜索树,因为这里的判断逻辑只涉及了根节点和它的子节点,只有两层的范围,无法判断到第三层第四层,甚至更多层以下,所以单纯的简单依靠根节点大于左节点,小于右节点来判断是行不通的。

3.代码展示

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    //已经遍历的序列的最大值
    TreeNode max;
    public boolean isValidBST(TreeNode root) {
        //如果节点为空,返回true
        if(root == null){
            return true;
        }
        //左
        boolean left = isValidBST(root.left);
        if(!left){
            return false;
        }
        //根
        //当前值小于已有序列的最大值,返回false
        if(max != null && root.val <= max.val){
            return false;
        }
        //更新序列的最大值
        max = root;
        //右
        boolean right = isValidBST(root.right);
        //返回验证的结果
        return right;
    }
}

4.总结

        这道题如果对树的遍历和二叉搜索树熟悉的话,一下子就能做出来,不熟悉的话,有可能会踩坑,是一道不错的题目。今天就简单bb到这里,祝大家刷题愉快~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xiao--xin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值