夯实算法-验证二叉搜索树

200 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的33天,点击查看活动详情

题目:LeetCode

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

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

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

示例 1: tree1.jpg

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

示例 2:

tree2.jpg

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

提示:

  • 树中节点数目范围在[1,104][1, 10^4] 内
  • 231<=Node.val<=2311-2^{31} <= Node.val <= 2^{31} - 1

解题思路

从题目给出的定义来看,所有左子节点小于根节点,根节点小于所有右子节点,并且左子树也是BST,右子树也有。

那么,如果以中序来遍历此树,如果得到的列表是严格递增顺序,那么肯定就是一个有效的 BST。所以,可以用这个来验证。

方式一:以中序遍历二叉树,如果节点值的顺序严格递增,则是有效的BST。可以用迭代式遍历,记录上一个节点,一旦发现它们不是严格递增,就返回false。

方式二:换个角度来说,左子树要小于根,那么根就是左子的上界(upper),右子树大于根根是其下界(lower) ,如此递归下去才能正确验证BST。

代码实现

class Solution {
    public boolean isValidBST(TreeNode root) {
        TreeNode curr = root;
        TreeNode prev = null;
        Stack < TreeNode > stack = new Stack < > ();
        while (curr != null || !stack.isEmpty()) {
            while (curr != null) {
                stack.push(curr);
                curr = curr.left;
            }
            curr = stack.pop();
            if (prev != null && prev.val >= curr.val) {
                return false;
            }
            prev = curr;
            curr = curr.right;
        }

        return true;
    }
}

运行结果

Snipaste_2022-12-31_20-46-06.png

复杂度分析

  • 空间复杂度:O(1)O(1)
  • 时间复杂度:O(n)O(n)

掘金(JUEJIN)  一起分享知识, Keep Learning!