1.问题描述
给你一个二叉树的根节点 root
,判断其是否是一个有效的二叉搜索树。
有效 二叉搜索树定义如下:
- 节点的左子树只包含 小于 当前节点的数。
- 节点的右子树只包含 大于 当前节点的数。
- 所有左子树和右子树自身必须也是二叉搜索树。
示例1
输入:root = [2,1,3] 输出:true
示例2
输入:root = [5,1,4,null,null,3,6] 输出:false 解释:根节点的值是 5 ,但是右子节点的值是 4 。
提示
- 树中节点数目范围在
[1, 104]
内 -231 <= Node.val <= 231 - 1
难度等级
中等
题目链接
2.解题思路
这道验证二叉搜索树的题,如果树的遍历和二叉搜索树概念熟悉的人,可以很快的做出来。我们对二叉搜索树进行中序遍历的话,二叉搜索树中的节点会按照升序输出,也就是从小到大输出。所以我们想要判断它是否是一个二叉搜索树,直接将它中序遍历,判断是否是升序输出即可。
在升序遍历之前,我们需要定义一个变量来存储已有序列的最大值,也就是当前序列最后遍历出来的那个节点。
//已经遍历的序列的最大值
TreeNode max;
接着,我们要来确定递归结束的逻辑,如果节点为空,那就返回true,这没什么难度。
//如果节点为空,返回true
if(root == null){
return true;
}
然后,我们就可以按照中序遍历的模版进行遍历了。
先递归调用当前方法遍历左子树,判断左子树是否为二叉搜索树,如果不是,直接返回false。
//左
boolean left = isValidBST(root.left);
if(!left){
return false;
}
接着,进行单层递归逻辑的处理。判断已有序列的最大值是否存在,如果存在的话,再判断当前节点的值是否大于已有序列的最大值,如果小于等于已有序列的最大值,那么序列就不是升序的,该二叉树也不是二叉搜索树,直接返回false;如果大于已有序列的最大值,则更新已有序列的最大值。
//根
//当前值小于已有序列的最大值,返回false
if(max != null && root.val <= max.val){
return false;
}
//更新序列的最大值
max = root;
最后递归调用当前方法遍历右子树,判断右子树是否为二叉搜索树,并将结果直接返回。
//右
boolean right = isValidBST(root.right);
//返回验证的结果
return right;
这里要提一个小坑,是我已经一开始做题踩到的。我们一看到二叉搜索树,很容易就想到根节点大于左节点,小于右节点,然后就直接用这个逻辑来递归判断是不是二叉搜索树了。这种情况下,如果右子树的左子树的值小于当前的根节点的话,但是按照真正的二叉搜索树的定义,右边的节点必须全部大于根节点,所以这种情况是被误判为二叉搜索树,因为这里的判断逻辑只涉及了根节点和它的子节点,只有两层的范围,无法判断到第三层第四层,甚至更多层以下,所以单纯的简单依靠根节点大于左节点,小于右节点来判断是行不通的。
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 {
//已经遍历的序列的最大值
TreeNode max;
public boolean isValidBST(TreeNode root) {
//如果节点为空,返回true
if(root == null){
return true;
}
//左
boolean left = isValidBST(root.left);
if(!left){
return false;
}
//根
//当前值小于已有序列的最大值,返回false
if(max != null && root.val <= max.val){
return false;
}
//更新序列的最大值
max = root;
//右
boolean right = isValidBST(root.right);
//返回验证的结果
return right;
}
}
4.总结
这道题如果对树的遍历和二叉搜索树熟悉的话,一下子就能做出来,不熟悉的话,有可能会踩坑,是一道不错的题目。今天就简单bb到这里,祝大家刷题愉快~