leetcode: 验证二叉搜索树

题目:

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

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

节点的左子树只包含小于当前节点的数。

节点的右子树只包含大于当前节点的数。

所有左子树和右子树自身必须也是二叉搜索树。

示例 1:

输入:

    2

   / \

  1   3

输出: true

示例 2:

输入:

    5

   / \

  1   4

     / \

    3   6

输出: false

解释: 输入为: [5,1,4,null,null,3,6]。

     根节点的值为 5 ,但是其右子节点值为 4 。

解法1 递归方式

 递归方式的话,如果按照我们一惯思想,会认为只要判断左子树小于父节点,右子树大于父节点即可,但实际并不是这样的,可能出现这样一种情况,下图,你用这样的思路去解,那么还是对的,但实际情况并非如此,如图所示,下面的就不符合二叉搜索树了。

所以我们需要再每次递归的时候,要传入两个参数,最大值和最小值,最大值则主要相对于左子树来说,他的所有元素,必须比这个最大值小,而最小值,则相对于右子树来说,他的所有元素要比这个最小值来的大

 只有这样才满足条件

 那么递归的话,又到了递归的三个条件

 1 递归的出口

 2 递归函数的作用

 3 返回值

 递归出口:,则是没有节点的时候,则返回true

 递归函数作用: 也就是根据我们传入的最大值和最小值,分别去判断该树下的左右子树是否满足条件

 返回值: 满足条件返回true,不满足返回false

代码如下:

/**
 * 判断是否是二叉搜索树
 *   思路: 递归的方式: 设置下限值和上限值
 *         每次判断是如果左子树的的值大于节点值,则返回false
 *         如果右子树的值小于上限值,则返回flase
 * @param root
 * @return
 */
public static boolean isValidBST(TreeNode root) {
    return helpValidBST(root,null,null);
}

public static boolean helpValidBST(TreeNode root, Integer min, Integer max) {
    // 1. 递归出口
    if (root == null) {
        return true;
    }

    int val = root.val;
    // 2. 如果值小于最小值,不符合,相对于右子树进入递归
    if(min!=null && val <= min){
        return false;
    }
    // 值大于最大值,则表示不对,相对于左子树进入递归
    if(max != null && val >= max) {
        return false;
    }
    // 3. 递归,对于左子树,则不能大于最大值
    if(!helpValidBST(root.left,min,val))return false;
    // 对于右子树,则不能小于最小值
    if(!helpValidBST(root.right,val,max)) return false;

    return true;
}

 

解法2 中序遍历的方式

中序遍历: 先访问左节点,再访问根节点,再访问右节点。

使用中序遍历方式,这里的解法有两种,一种是你可以先中序遍历出来,再来判断是否该数组是有序的,如果有序,则表示是二叉搜索树。

另外一种解法,则是你在遍历的时候,当遍历到下一个节点的时候,判断是否比上一个节点大,如果不是的话,则不满足条件,直接退出。不需要遍历完。

代码如下:

/**
 *  使用中序遍历方式实现
 * @param root
 * @return
 */
public static boolean isValidBST1(TreeNode root) {

    Stack<TreeNode> stack = new Stack();

    int inorder = -1;

    while (!stack.isEmpty() || root != null) {
        // 1. 将左子树压入栈中
        while (root != null) {
            stack.push(root);
            root = root.left;
        }
        // 2. 出栈
        root = stack.pop();
        // 如果该值比上一个值小,则不符合条件
        if (root.val <= inorder) return false;
        // inorder是保存值,即遍历的的值,用来与下一个值进行比较
        inorder = root.val;
        // 找右子树
        root = root.right;
    }
    return true;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值