合法二叉搜索树[回溯拿到中序定义的前驱节点]

前言

对于树的处理,遍历是基本功。对于二叉搜索树的合法性,用中序遍历定义中前驱和后继来判断即可。

一、合法二叉搜索树

在这里插入图片描述

二、两种解法–两种理解

package everyday;

// 合法二叉搜索树。
public class IsValidBST {
    /*
    target:判断二叉树是否为二叉搜索树。
    二叉搜索树定义,左 < 中 < 右。
    1-由于这个小于关系,为二叉树的中序遍历,所以可记录中序遍历下的前驱节点pre,然后比较root和pre的大小关系。
     */
    public boolean isValidBST(TreeNode root) {
        // 该条路径到达null节点,结束递归。
        if (null == root) return true;
        // 判断左子树是否满足条件。
        boolean flag = isValidBST(root.left);
        // 左子树不满足条件,则该树也不是二叉搜索树。
        if (!flag) return false;
        // 左子树满足条件,用左子树的最右节点pre和root相比,看是否满足条件。
        // 不满足条件,该树也不是二叉搜索树。
        if (pre >= root.val) return false;
        // 满足条件,把前驱替换,继续判断右子树是否满足。
        pre = root.val;
        // 右边满足了,加上刚才的左边,那么整棵树都满足二叉搜索树条件;右边不满足,那么则整棵树不为二叉搜索树。
        return isValidBST(root.right);
    }

    // bug1:1 << 63 = Integer.MIN_VALUE,因为1默认int。
    // private long pre = 1 << 63;
    private long pre = 1l << 63;


    // Definition for a binary tree node.
    public class TreeNode {
        int val;
        TreeNode left;
        TreeNode right;

        TreeNode(int x) {
            val = x;
        }
    }

}

// 能否不用全局变量pre,利用回溯来返回前驱(针对root的前驱) + 传入前驱(针对右子树最左孩子)。
class IsValidBST2 {
    /*
    target:判断二叉树是否为二叉搜索树。
    二叉搜索树定义,左 < 中 < 右。
    每次返回一个中序遍历的前驱节点和root比较即可。

    root的前驱就是其左子树的最右孩子;右子树最左孩子的前驱就是root。
     */
    public boolean isValidBST(TreeNode root) {
        inOrder(root, null);
        return flag;
    }

    private TreeNode inOrder(TreeNode root, TreeNode pre) {
        // 递归到叶子节点的子节点,终止递归。
        if (null == root) return null;
        // 当有子树已经不满足二叉搜索树了,直接剪枝。
        if (!flag) return null;
        // 先左递归
        TreeNode left = inOrder(root.left, pre);
        // 左子树不为空,要和左子树最右节点比;否则和pre比。
        // 砍掉右子树。
        if (left != null && left.val >= root.val || left == null && pre != null && pre.val >= root.val) {
            System.out.println(left.val);
            flag = false;
            return null;
        }
        TreeNode right = inOrder(root.right, root);
        // 叶子节点 || 有左无右,都返回root即可。
        if (right == null) return root;
        // 有左有右 || 无左有右,都返回最右节点即可。
        return right;
    }

    private boolean flag = true;


    // Definition for a binary tree node.
    public class TreeNode {
        int val;
        TreeNode left;
        TreeNode right;

        TreeNode(int x) {
            val = x;
        }
    }

}

总结

1)处理好任意一颗子树,就处理好了整颗树,这是二叉递归结构的魅力。

参考文献

[1] LeetCode 合法二叉搜索树

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值