Leetcode 深度优先搜索 (3)
98. 验证二叉搜索树
给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。
有效 二叉搜索树定义如下:
- 节点的左子树只包含 严格小于 当前节点的数。
- 节点的右子树只包含 严格大于 当前节点的数。
- 所有左子树和右子树自身必须也是二叉搜索树。
示例1:
输入: root = [2,1,3]
输出: true
解题思路
思路一:中序遍历法
核心思想:BST的中序遍历结果应该是严格递增的序列
步骤:
- 对二叉树进行中序遍历(左-根-右)
- 检查遍历序列是否严格递增
- 如果是递增序列,则为有效BST;否则不是
代码实现
/*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val = val; }* TreeNode(int val, TreeNode left, TreeNode right) {* this.val = val;* this.left = left;* this.right = right;* }* }*/
class Solution {public boolean isValidBST(TreeNode root) {List<Integer> inorderList = new ArrayList<>();inorderTraversal(root, inorderList);// 检查中序遍历结果是否严格递增for (int i = 1; i < inorderList.size(); i++) {if (inorderList.get(i) <= inorderList.get(i - 1)) {return false;}}return true;}/*** 中序遍历二叉树* @param node 当前节点* @param result 存储遍历结果的列表*/private void inorderTraversal(TreeNode node, List<Integer> result) {if (node == null) {return;}// 左 -> 根 -> 右inorderTraversal(node.left, result);result.add(node.val);inorderTraversal(node.right, result);}
}
思路二:递归边界法(推荐)
核心思想:为每个节点维护一个有效值范围
步骤:
- 初始时根节点的值范围是 (-∞, +∞)
- 对于左子树,更新上界为当前节点值
- 对于右子树,更新下界为当前节点值
- 递归验证每个节点的值是否在其有效范围内
代码实现
/*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val = val; }* TreeNode(int val, TreeNode left, TreeNode right) {* this.val = val;* this.left = left;* this.right = right;* }* }*/
class Solution {public boolean isValidBST(TreeNode root) {return validate(root, null, null);}/*** 递归验证节点是否在有效范围内* @param node 当前节点* @param lower 下界(不包含)* @param upper 上界(不包含)* @return 当前子树是否为有效BST*/private boolean validate(TreeNode node, Integer lower, Integer upper) {// 空节点认为是有效的BSTif (node == null) {return true;}// 检查当前节点值是否在有效范围内if (lower != null && node.val <= lower) {return false;}if (upper != null && node.val >= upper) {return false;}// 递归验证左右子树// 左子树:上界更新为当前节点值// 右子树:下界更新为当前节点值return validate(node.left, lower, node.val) && validate(node.right, node.val, upper);}
}
思路三:递归比较法
核心思想:直接利用BST的定义进行递归验证
步骤:
- 验证当前节点值是否满足BST条件
- 递归验证左子树和右子树
- 注意要传递上下界信息,而不是仅与父节点比较
代码实现
class Solution {public boolean isValidBST(TreeNode root) {return isValidBSTHelper(root, Long.MIN_VALUE, Long.MAX_VALUE);}/*** 递归验证BST的辅助方法* @param node 当前节点* @param min 最小边界值* @param max 最大边界值* @return 当前子树是否为有效BST*/private boolean isValidBSTHelper(TreeNode node, long min, long max) {// 基础情况:空节点是有效的BSTif (node == null) {return true;}// 检查当前节点是否违反BST性质if (node.val <= min || node.val >= max) {return false;}// 递归检查左右子树// 左子树:所有节点必须小于当前节点值,更新max为当前节点值// 右子树:所有节点必须大于当前节点值,更新min为当前节点值return isValidBSTHelper(node.left, min, node.val) && isValidBSTHelper(node.right, node.val, max);}}