树与图中等3 种解法

#98验证二叉搜索树

判断一棵二叉树是否满足所有左子树值严格小于根、右子树值严格大于根。

#二叉搜索树#深度优先搜索#中序遍历

解题主线

01

上下界法把祖先约束一路传给子树,不能只比较父子节点。

02

二叉搜索树的中序遍历必须严格递增。

解法 1递归上下界

为每个节点维护来自所有祖先的开区间 (lower, upper)。

时间复杂度

O(n)

空间复杂度

O(h)

98. 验证二叉搜索树 · 递归上下界
import java.util.*;

class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;

    TreeNode(int val) {
        this.val = val;
    }
}

class Solution {
    public boolean isValidBST(TreeNode root) {
        return validate(root, Long.MIN_VALUE, Long.MAX_VALUE);
    }

    private boolean validate(TreeNode node, long lower, long upper) {
        if (node == null) return true;
        if (node.val <= lower || node.val >= upper) return false;
        return validate(node.left, lower, node.val)
                && validate(node.right, node.val, upper);
    }
}

为每个节点维护来自所有祖先的开区间 (lower, upper)。

解法 2递归中序遍历

中序访问时与前一个节点值比较,用局部数组承载跨递归帧状态。

时间复杂度

O(n)

空间复杂度

O(h)

98. 验证二叉搜索树 · 递归中序遍历
import java.util.*;

class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;

    TreeNode(int val) {
        this.val = val;
    }
}

class Solution {
    public boolean isValidBST(TreeNode root) {
        return inorder(root, new long[] {Long.MIN_VALUE});
    }

    private boolean inorder(TreeNode node, long[] previous) {
        if (node == null) return true;
        if (!inorder(node.left, previous)) return false;
        if (node.val <= previous[0]) return false;
        previous[0] = node.val;
        return inorder(node.right, previous);
    }
}

中序访问时与前一个节点值比较,用局部数组承载跨递归帧状态。

解法 3迭代中序遍历

显式栈模拟中序遍历,逐个检查输出序列是否严格递增。

时间复杂度

O(n)

空间复杂度

O(h)

98. 验证二叉搜索树 · 迭代中序遍历
import java.util.*;

class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;

    TreeNode(int val) {
        this.val = val;
    }
}

class Solution {
    public boolean isValidBST(TreeNode root) {
        Deque<TreeNode> stack = new ArrayDeque<>();
        TreeNode current = root;
        long previous = Long.MIN_VALUE;
        while (current != null || !stack.isEmpty()) {
            while (current != null) {
                stack.push(current);
                current = current.left;
            }
            current = stack.pop();
            if (current.val <= previous) return false;
            previous = current.val;
            current = current.right;
        }
        return true;
    }
}

显式栈模拟中序遍历,逐个检查输出序列是否严格递增。

边界与易错点

  • 节点值可能等于 int 边界,上下界应使用 long。
  • 递归中序的前驱值不能残留在多次调用之间,应使用方法内局部状态。
整理来源

由旧仓库源码复核、去重并整理;展示代码已按 Java 21 语义修正明显问题。

leetcode/src/main/java/tree/Q98_isValidBST.java