跟着小码学算法Day21:验证二叉搜索树
一、二叉搜索树(BST)的定义
-
对于任意节点
node:-
其 左子树中所有节点的值 必须 严格小于
node.val -
其 右子树中所有节点的值 必须 严格大于
node.val -
左右子树也必须是 BST
-
注意:不是只比较当前节点和左右孩子!
例如下面这棵树不是 BST:
5/ \1 6/ \3 7 ← 3 < 5,违反了“右子树所有节点 > 根”的规则
二、算法思想与模板
1,上下界约束法(自顶向下递归)
- 思想:每个节点的值都必须落在一个合法区间
(min, max)内。- 根节点:区间为
(-∞, +∞) - 左子节点:区间变为
(-∞, root.val) - 右子节点:区间变为
(root.val, +∞) - 递归传递边界
- 根节点:区间为
- 实现:递归函数
isValid(node, min, max)
实例:
class Solution {public boolean isValidBST(TreeNode root) {return dfs(root, null, null);}private boolean dfs(TreeNode node, Integer min, Integer max) {if (node == null) return true;if (min != null && node.val <= min) return false;if (max != null && node.val >= max) return false;return dfs(node.left, min, node.val) && dfs(node.right, node.val, max);}
}
2,中序迭代
-
思想:BST 的中序遍历结果一定是 严格递增序列。
-
验证方法:在遍历过程中,记录前一个访问的节点值(或引用),检查是否
pre >= current,若是则非法。
// 使用普通迭代中序遍历(非统一写法,更稳定)
class Solution {public boolean isValidBST(TreeNode root) {Stack<TreeNode> stack = new Stack<>();TreeNode curr = root;TreeNode pre = null;while (curr != null || !stack.isEmpty()) {while (curr != null) {stack.push(curr);curr = curr.left;}curr = stack.pop();if (pre != null && pre.val >= curr.val) return false;pre = curr;curr = curr.right;}return true;}
}
三、典型例题
98. 验证二叉搜索树 - 力扣(LeetCode)
class Solution {public boolean isValidBST(TreeNode root) {if (root == null) return true;Stack<TreeNode> stack = new Stack<>();TreeNode pre = null;stack.push(root);while (!stack.isEmpty()) {TreeNode curr = stack.peek();if (curr != null) {stack.pop();// 入栈顺序:右 → 中 → null → 左if (curr.right != null) stack.push(curr.right);stack.push(curr); // 中stack.push(null); // 标记if (curr.left != null) stack.push(curr.left); // 左(不是 curr!)} else {stack.pop(); // 弹出 nullTreeNode node = stack.pop(); // 弹出实际节点if (pre != null && pre.val >= node.val) {return false;}pre = node;}}return true;}
}
