题目详情
给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。
有效 二叉搜索树定义如下:
- 节点的左子树只包含 小于 当前节点的数。
- 节点的右子树只包含 大于 当前节点的数。
- 所有左子树和右子树自身必须也是二叉搜索树。
提示:
- 树中节点数目范围在[1, 104] 内
- -2^31 <= Node.val <= 2^31 - 1
示例 1:
输入:root = [2,1,3]
输出:true
2
/ \
1 3
示例 2:
输入:root = [5,1,4,null,null,3,6]
输出:false
解释:根节点的值是 5 ,但是右子节点的值是 4 。
5
/ \
1 4
/ \
3 6
Java代码(递归)
public boolean isValidBST(TreeNode root) {
return isValidBST(root, Long.MIN_VALUE, Long.MAX_VALUE);
}
public boolean isValidBST(TreeNode root, long minVal, long maxVal) {
if (root == null)
return true;
//每个节点如果超过这个范围,直接返回false
if (root.val >= maxVal || root.val <= minVal)
return false;
//这里再分别以左右两个子节点分别判断,
//左子树范围的最小值是minVal,最大值是当前节点的值,也就是root的值,因为左子树的值要比当前节点小
//右子数范围的最大值是maxVal,最小值是当前节点的值,也就是root的值,因为右子树的值要比当前节点大
return isValidBST(root.left, minVal, root.val) && isValidBST(root.right, root.val, maxVal);
}
总结
递归的结束条件是遇到了叶子节点,如果遇到了叶子节点就返回true。如果当前节点的值大于最大值或者小于最小值那么返回false。然后用递归判断左子树和右子树是否是二叉搜索树,这时需要将当前节点的值来判断左子树是否符合条件,因为左节点的值永远小于父节点,所以需要将当前节点值作为左子树的最大值,这样就能将左子树的所有值限制为小于父节点,右子树同理。
Java代码(中序遍历)
//前一个结点,全局的
TreeNode prev;
public boolean isValidBST(TreeNode root) {
if (root == null)
return true;
//访问左子树
if (!isValidBST(root.left))
return false;
//访问当前节点:如果当前节点小于等于中序遍历的前一个节点直接返回false。
if (prev != null && prev.val >= root.val)
return false;
prev = root;
//访问右子树
if (!isValidBST(root.right))
return false;
return true;
}
总结
根据二叉搜索树的性质,中序遍历二叉搜索树,遍历得到的结果一定是有序的,所以在遍历过程中,判断当前节点是否大于前一个节点,如果不是有序,那么返回false。