递归调用详解 二叉排序树LeetCode

验证二叉搜索树

给定一个二叉树,判断其是否是一个有效的二叉搜索树。

假设一个二叉搜索树具有如下特征:

节点的左子树只包含小于当前节点的数。
节点的右子树只包含大于当前节点的数。
所有左子树和右子树自身必须也是二叉搜索树。

递归调用详解   二叉排序树LeetCode

思路:

方法1  对于每一个结点,步骤一  :也就是每一次都遍历左子树寻找左子树最大的节点,是否小于根节点。步骤二:遍历右子树找到右子树最小的节点,看是否大于根节点

class Solution {
    private TreeNode getMax(TreeNode node){
        while(node.right!=null){//不会为null
            node = node.right;
        }
        return node;
    }
     private TreeNode getMin(TreeNode node){
        while(node.left!=null){//不会为null
            node = node.left;
        }
        return node;
    }
    public boolean isValidBST(TreeNode root) {
        if(root == null) return true;//中序遍历所有节点,每一个节点强制小于后一个节点
        if(root.left!=null&&getMax(root.left).val>=root.val){
            return false;// 左边的最大值大于根节点,错误
        }
        if(root.right!=null && getMin(root.right).val<=root.val){
            return false;//右边的最小值小于root,错误
        }
        return isValidBST(root.left)&&isValidBST(root.right);//如果根节点没问题,分别测试左右子树
    }
}

  优点:好理解。缺点:每次都遍历一遍左子树和右子树,重复太多。

 方法2: 步骤一:在遍历左子树的时候不断的更新左子树的值域  (root.left,max,root.val),步骤二 在遍历右子树的时候不断的更新右子树的值域(root.right,root.val,min).

class Solution {
    private boolean isOrder(TreeNode root,long min, long max){
        if(root==null) return true;
        if(root.val<=min || root.val>=max){
            return false;
        }
        return isOrder(root.left,min,root.val)&&isOrder(root.right,root.val,max);
    }
    public boolean isValidBST(TreeNode root) {
        return isOrder(root,Long.MIN_VALUE,Long.MAX_VALUE);//如果根节点没问题,分别测试左右子树
    }
}

 非常高效的方法,不太好理解,就把一棵树看成只有三个节点能相对简单些。方法3:步骤一,考虑到是平衡二叉树,用中序遍历,可以得到一个有序数列。步骤二,每次比较当前节点和它的前一个节点。前一个节点用pre来表示,初始值Long.MAX_VALUE。如果小于等于前一个节点,那么返回false。

class Solution {
    private long pre = Long.MIN_VALUE;//当前节点的前一个值,如果当前节点比它前面的值还小,返回false
    public boolean isValidBST(TreeNode root) {
        if(root == null) return true;
        if(!isValidBST(root.left)){
            return false;
        }
        if(root.val<=pre){
            return false;
        }
        pre = root.val;
        return isValidBST(root.right);
    }
}