LeetCode98 验证二叉搜索树

240 阅读2分钟

「这是我参与11月更文挑战的第10天,活动详情查看:2021最后一次更文挑战

验证二叉搜索树

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

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

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

image.png

解法

错误解法

这道题虽然不是很难,但很容易踩坑,我刚拿到这道题的时候,想的很简单,迭代的把每层的根节点和左子节点,右子节点做比较,不满足根节点val值大于左子节点val值,小于右子节点val值的返回false,迭代完还没有返回false则返回true。但是这样做很容易存在两个问题

  • 每层虽然满足根节点val值大于左子节点val值,但左子节点那棵树中可以存在值大于根节点的值
  • 每层虽然满足根节点val值小于右子节点val值,但右子节点那棵树中可以存在值小于根节点的值

递归正确解法

  • 递归的参数和返回值:每次递归的参数是TreeNode节点,返回的是true和false,用以验证该层递归的子树是否符合搜索二叉树的特性
  • 递归的终止条件:当递归传入的是空节点时,证明上一层递归是叶子结点,这层递归返回true
  • 递归的单层逻辑:我们画出一个正常搜索二叉树,并写出它的中序遍历,可以发现,整个值是递增的,也就是按中序遍历防暑读取的节点val值,一定比前一个节点大,我们可以比较pre.val和root.val(当前遍历的节点值)并记录preNode,然后根据递归得到的左子树和右子树结果,返回true和false给上一层递归

F247091486EC77C302594CADA4B59877.png

// 递归解法
var isValidBST = function(root) {
    let pre = null;
    const inOrder = (root) => {
        if (root === null)
            return true;
        let left = inOrder(root.left);
        if (pre !== null && pre.val >= root.val)
            return false;
        pre = root;

        let right = inOrder(root.right);
        return left && right;
    }
    return inOrder(root);
};