98:验证二叉搜索树

问题描述

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

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

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

示例

输入:
    2
   / \
  1   3
输出: true
输入:
    5
   / \
  1   4
     / \
    3   6
输出: false
解释: 输入为: [5,1,4,null,null,3,6]。
     根节点的值为 5 ,但是其右子节点值为 4

思路

这题一开始想用优雅的递归来做。但是我搞不懂怎么返回左子树最大的值和右子树最小的值。(java不好实现,Python可以实现) 如果左子树最大的值都比根结点的值小,同理,右子树最小的值都比根结点元素大,那么肯定符合题意。
那么,另辟蹊径。 用层序遍历来做(其实什么遍历都可以,重点是不用递归实现的还是层序遍历方便)。然后判定左子树的元素是否都小于根结点的值。右子树是否都大于。 把所有的结点都判定一遍,就得到答案了。(方法一)

贼心不死,想了想既然不能由下往上返回值,那么能不能由上到下传参的方式来解决这个问题呢? 当然可以!每棵子树中的值都被限定了一定的范围。不失一般性,我们考虑很大的一棵树。 我们讨论的结点是某棵树的左子树的右子树的根结点。
那么,这棵右子树的根结点的值的上限由整棵树的树根决定,下限由它自己的根决定。 所以我们要往下传递两个参数,一个是当前结点的上限,一个是当前结点的下限。 那么,没有上下限时怎么办?好办,Java有包装类,用包装类传递,这样就能传null了。没有上下线就传null呗。(方法二)

还有,不要忘记二叉搜索树(二叉排序树)的一个重要性质:中序遍历这棵树得到一个有序序列。 所以我们设置一个last值记录中序遍历的上一个值。判断即可。(方法三)

方法一

public boolean isValidBST1(TreeNode root) {
        if(root == null) return true;
        boolean childFlag = isValidBST1(root.left)&&isValidBST1(root.right);
        if(!childFlag) return false;
        ArrayList<Integer> left = getAllVal(root.left);
        ArrayList<Integer> right = getAllVal(root.right);
        for(int l:left) if(l >= root.val) return false;
        for(int r:right) if(r <= root.val) return false;
        return true;
    }
    private ArrayList<Integer> getAllVal(TreeNode root){
        if(root == null) return new ArrayList<>();
        ArrayList<Integer> res = new ArrayList<>();
        Queue<TreeNode> queue = new LinkedList<>();
        queue.add(root);
        while(queue.size() > 0){
            TreeNode curNode = queue.poll();
            res.add(curNode.val);
            if(curNode.left != null) queue.add(curNode.left);
            if(curNode.right != null) queue.add(curNode.right);
        }
        return res;
    }

方法二

public boolean isValidBST(TreeNode root){
        if(root == null) return true;
        return next(root,null,null);
    }
    private boolean next(TreeNode root, Integer max, Integer min){
        if(root == null) return true;
        int val = root.val;
        if(min != null && val <= min) return false;
        if(max != null && val >= max) return false;
        if(!next(root.left,val,min)) return false;
        return next(root.right, max, val);
    }

方法三

class Solution {
    Integer last;
    public boolean isValidBST(TreeNode root) {
        if(root == null) return true;
        if(!isValidBST(root.left)) return false;
        if(last != null && last >= root.val) return false;
        last = root.val;
        return isValidBST(root.right);
    }
}
发布了464 篇原创文章 · 获赞 21 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/weixin_41687289/article/details/105320521