Leetcode会员尊享面试100题:333.最大二叉搜索子树

给定一个二叉树,找到其中最大的二叉搜索树(BST)子树,并返回该子树的大小。其中,最大指的是子树节点数最多的。

**二叉搜索树(BST)**中的所有节点都具备以下属性:

  • 左子树的值小于其父(根)节点的值。

  • 右子树的值大于其父(根)节点的值。

**注意:**子树必须包含其所有后代。

示例 1:

复制代码
输入:root = [10,5,15,1,8,null,7]
输出:3
解释:本例中最大的 BST 子树是高亮显示的子树。返回值是子树的大小,即 3 。

示例 2:

复制代码
输入:root = [4,2,7,2,3,5,null,2,null,null,null,null,null,1]
输出:2

提示:

  • 树上节点数目的范围是 [0, 104]
  • -104 <= Node.val <= 104

进阶: 你能想出 O(n) 时间复杂度的解法吗?

直接上代码:

java 复制代码
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public int largestBSTSubtree(TreeNode root) {
        /**空树判断 */
        if(root == null) {
            return 0;
        }
        /**获取root的info信息 */
        Info info = getInfo(root);
        return info.numOfNodes;
    }

    public Info getInfo(TreeNode root) {
        /**叶子节点的判断,叶子节点是BST,节点数是1,最大值和最小值都是自己的值 */
        if(root.left == null && root.right == null) {
            return new Info(true, 1, root.val, root.val);
        }
        /**目前只有自己的信息,那就是先按叶子节点的信息设置,后面根据左右子树的信息再修改 */
        boolean isBST = true;
        int numOfNodes = 1;
        int minValue = root.val;
        int maxValue = root.val;
        /**定义在外面是因为外面要用 */
        Info leftInfo = null;
        Info rightInfo = null;
        /**如果有左子树,再获取左子树的信息,左右子树的信息都不设置节点的数量 */
        if(root.left != null) {
            leftInfo = getInfo(root.left);
            isBST = isBST && leftInfo.isBST && root.val > leftInfo.maxValue;
            minValue = Math.min(minValue, leftInfo.minValue);
            maxValue = Math.max(maxValue, leftInfo.maxValue);
        }
        if(root.right != null) {
            rightInfo = getInfo(root.right);
            isBST = isBST && rightInfo.isBST && root.val < rightInfo.minValue;
            minValue = Math.min(minValue, rightInfo.minValue);
            maxValue = Math.max(maxValue, rightInfo.maxValue);
        }
        /**整棵树是BST,就根据左右子树的信息设置,同时加上所有的节点数 */
        if(isBST) {
            numOfNodes += root.left != null? leftInfo.numOfNodes : 0;
            numOfNodes += root.right != null? rightInfo.numOfNodes : 0;
            minValue = root.left != null? leftInfo.minValue : root.val;
            maxValue = root.right != null? rightInfo.maxValue : root.val;
        } else {
            /**如果不是的话,谁的numOfNodes(以当前节点为根的树上所有的BST里的最大节点树)大取谁的,
            这样即使自己不是也可以把信息带到树的根节点 */
            numOfNodes = Math.max(leftInfo != null? leftInfo.numOfNodes : 0 , rightInfo != null? rightInfo.numOfNodes : 0);
        }
        return new Info(isBST, numOfNodes, minValue, maxValue);
    }
}
/**根据题目意思,这个树本身可能不是二叉搜索树,我们需要在它身上找到是二叉搜索树并且节点最多的
所以我们需要以下几个信息:1.是否是二叉搜索树 2.节点数量 3.最大值 4.最小值
其中3和4是用来判断是在知道当前树的左右子树的信息时候判断当前树是否是二叉搜索树用的*/
class Info {
    /**当前树是不是搜索二叉树 */
    boolean isBST;
    /**当前树上最大的搜索二叉树的节点数量 */
    int numOfNodes;
    /**当前树的最大值 */
    int maxValue;
    /**当前树的最小值 */
    int minValue;

    public Info(boolean isBST, int numOfNodes, int minValue, int maxValue) {
        this.isBST = isBST;
        this.numOfNodes = numOfNodes;
        this.minValue = minValue;
        this.maxValue = maxValue;
    }
}

运行结果

相关推荐
AI成长日志11 分钟前
【GitHub开源项目专栏】黑客松项目架构模式解析:微服务、事件驱动与Serverless实战
算法
人道领域11 分钟前
【LeetCode刷题日记:24】两两交换链表
算法·leetcode·链表
北顾笙98014 分钟前
day16-数据结构力扣
数据结构·算法·leetcode
AI成长日志26 分钟前
【算法学习专栏】动态规划基础·简单三题精讲(70.爬楼梯、118.杨辉三角、121.买卖股票的最佳时机)
学习·算法·动态规划
wsoz28 分钟前
Leetcode子串-day4
c++·算法·leetcode
@atweiwei30 分钟前
Go语言并发编程面试题精讲(下)
面试·golang·并发·channel
@atweiwei39 分钟前
Go语言并发编程面试题精讲(上)
java·开发语言·面试·golang·channel
汀、人工智能1 小时前
[特殊字符] 第27课:环形链表II
数据结构·算法·链表·数据库架构··环形链表ii
会编程的土豆1 小时前
【数据结构与算法】二叉树大总结
数据结构·算法·leetcode
沉鱼.441 小时前
第十届题目
算法