Leetcode 98. 验证二叉搜索树 (Medium)

给你一个二叉树的根节点 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

思路:

        先确定一下分析方法,这个乍一看就看出了解决办法,就先理出一个大致思路,然后实现,因为有很多小细节,小问题可能是想而不到的,所以就需要运行,发现问题,再打补丁,使用这个分析方法可以让目的比较明确,效率也比较高。

        回归到本题,题目一看就是循环或者递归遍历,应该都是能够实现的,当需要遍历的分值多的时候,循环就显得比较复杂了,所以这道题我推荐递归。当然这道题也是用递归实现的,建立两个递归的分支函数,分别问检验左子树和检验右子树的函数,先分析一边,检验成功不好理解,先看怎么叫做检验失败然后再取反。

        对于左子树如果他其中有一个节点大于现在的父节点,就认为是检验失败的,这是题目中给的定义,看起来还是很朦胧,那么再细化,分析下一左右子树,左子树的左子树的左节点不能大于左子树的节点值,但是右子树就麻烦了,它不仅要大于左子树的节点值,而且要小于左子树的父节点值,上图

        就是3节点不仅要考虑和4的关系,更要考虑和5的关系,比5大比4小,显然不成立为false,举个例子而已,因为这个例子在4的时候就已经被淘汰了。

        所以传参的时候不仅要传节点这个必须的,还有root.val和父节点的值,在左子树下,root.val就是max,min看左子树的父节点是不是右子树。在右子树下也一样,然后上代码。

代码:

/**
 * 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 {
    public boolean isValidBST(TreeNode root) {
        // 一看树 一般就两大解决办法 循环+队列 或 递归
        // 先考虑递归 显然普通递归只能判断三个节点间是否符合二叉搜索树
        // 导致这个问题 一共两个情况就是 左子树的右节点可能大于根节点
        // 或者右子树的左节点可能小于根节点
        return verify0(root.left, root.val, null) && verify1(root.right, root.val, null);
    }
    public boolean verify0(TreeNode root, int max, Integer min) {
        if (root == null) return true;
        if (root.val >= max) return false;       
        // 验证左子树 min传null的话就是没有最小限制,这种情况就是左子树的左节点
        if (min != null && root.val <= min) return false;
        return verify0(root.left, root.val, min) && verify1(root.right, root.val, max);

    }
    public boolean verify1(TreeNode root, int min, Integer max) {
        // 验证右子树
        if (root == null) return true;
        if (root.val <= min) return false;
        // 验证右子树 max传null的话就是没有最大限制,这种情况就是右子树的右节点
        if (max != null && root.val >= max) return false;
        return verify0(root.left, root.val, min) && verify1(root.right, root.val, max);
    }
}

运行结果:

        

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值