验证二叉搜索树

132 阅读1分钟

Offer 驾到,掘友接招!我正在参与2022春招系列活动-刷题打卡任务,点击查看活动详情

一、题目

leetcode 验证二叉搜索树

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

二、题解

1.解读 二叉搜索树的定义是如果该二叉树的左子树不为空,则左子树上所有节点的值均小于它的根节点的值; 若它的右子树不空,则右子树上所有节点的值均大于它的根节点的值;它的左右子树也为二叉搜索树。

方法一 知道了二叉搜索树的定义,我们就只要判断是否满足这个定义即可。但是呢不能简单的判断当前节点下的左节点和右节点的大小,局部的子树合法不表示整个二叉树是合法的,例如[5, 1, 6, null, null, 3, 7],局部来看根节点5的左右节点1、6都是合法的,根节点6的左右节点3、7都是合法的;但是整体的根节点5的右子树中存在节点3明显是不合法的,所以我们不能单纯判断节点值的大小,需要判断节点值是否在某个范围内。具体的方便判断就使用递归函数来遍历二叉树isValidBST(root, min, max)root为需要验证的二叉树,同时root二叉树内节点值val要满足min < val < max,初始root树根节点不用判断范围所以min = max = null。然后递归判断左子树root.left,左子树的节点值都要小于根节点值max = root.val,以及判断右子树root.right,右子树的节点值都要大于根节点值min = root.val

方法二 根据二叉搜索树的定义我们可以知道,左节点、根节点、右节点的值按顺序一定是升序的,所以可以利用中序遍历,先遍历数的左节点,然后是根节点,最后再是右节点。所以可以直接遍历判断当前节点值是否大于前一个节点值,如果小于说明该二叉树不合法,否则就继续遍历。首先需要一个pre变量记录前一个节点值,然后当前节点不为空就继续,先递归判断当前节点的左子树,然后判断当前节点值如果小于等于前一个节点值pre就直接返回false,否则更新pre值为当前节点值,然后继续递归判断当前节点的右子树。

三、代码 方法一 Java代码

class Solution {
    public boolean isValidBST(TreeNode root) {
        return isValidBST(root, null, null);
    }
    public boolean isValidBST(TreeNode root, Integer min, Integer max) {
        if (root == null) {
            return true;
        }
        if (min != null && root.val <= min) {
            return false;
        }
        if (max != null && root.val >= max) {
            return false;
        }
        return isValidBST(root.left, min, root.val) && isValidBST(root.right, root.val, max);
    }
}

时间复杂度:O(n),递归遍历二叉树所以节点。

空间复杂度:O(n),递归遍历使用的空间。

方法二 Java代码

class Solution {
    Integer pre = null;
    public boolean isValidBST(TreeNode root) {
        if (root == null) {
            return true;
        }
        if (!isValidBST(root.left)) {
            return false;
        }
        if (pre != null && root.val <= pre) {
            return false;
        }
        pre = root.val;
        return isValidBST(root.right);
    }
}

时间复杂度:O(n),递归遍历二叉树所以节点。

空间复杂度:O(n),递归遍历使用的空间。