1.题目: (验证二叉搜索树)
给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。
有效 二叉搜索树定义如下:
节点的左子树只包含 小于 当前节点的数。
节点的右子树只包含 大于 当前节点的数。
所有左子树和右子树自身必须也是二叉搜索树。
2. 示例
3.解答步骤
思路都在注释上! 请大家自主阅读程序!
⭐ 本篇注意点: 应该为左右子树的数值判断,设定一个范围!
答:
首先了解到搜索树是什么?(左子树数值小于父结点, 右子树数值大于父结点)
// 针对于左递归(左子树), 最大值限定范围为父亲结点的数值
// 正对于右递归(右子树), 最小范限定范围为父亲结点的数值
/**
* 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 isValidBST(root, Long.MIN_VALUE, Long.MAX_VALUE);
}
// 我们重写一个方法
public boolean isValidBST(TreeNode root, long minVale, long maxValue) {
// 假如结点为空, 则代表该子节点已经没有值
// 并不会打破搜索树条件, 返回true确保程序继续运行
if(root == null) {
// 递归终止条件
return true;
}
// 这里我们来验证当前结点是否符合条件
// 1. 左子树结点值小于父结点值 (条件一)
// 2. 右子树节点值小于父结点值 (条件二)
// 因为我们左子树遍历 比较结点最大值范围为父亲结点的值
// 所以当 当前结点值大于 父亲结点时,破坏了上面注释条件一
// 所以返回false
// 而右子树遍历,比较结点最小范围是父亲结点的值
// 所以当右子树结点值小于父亲结点值时,破坏了注释条件二
// 所以返回false
// 针对 左子树,我们只要求最小值不小于 Long类型范围最小值
// 针对 右子树,我们只要求最大值不超过 Long类型范围的最大值
if (root.val<=minVale || root.val>=maxValue) {
// 当满足这两个条件(大于限定范围(父结点)最大值或最小值时)
return false;
}
// 然后递归返回
// 针对于左递归(左子树), 最大值限定范围为父亲结点的数值
// 正对于右递归(右子树), 最小范限定范围为父亲结点的数值
// 因为是 搜索树, 左子树小于父亲结点, 右子树大于父亲结点
return isValidBST(root.left, minVale, root.val) && isValidBST(root.right, root.val, maxValue);
}