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;
    }
}

运行结果

相关推荐
Aphasia3111 小时前
https连接传输流程
前端·面试
徐小夕1 小时前
万字长文!千万级文档 RAG 知识库系统落地实践
前端·算法·github
akunkuntaimei1 小时前
2026年高考数学各省真题及答案(完整版)
算法·高考
kyriewen1 小时前
CSS Container Queries:彻底告别 @media 写到手软,附 5 个真实布局案例
前端·css·面试
Hello:CodeWorld2 小时前
C 风格变参 vs C++ 变参模板:核心区别与选型指南
c语言·c++·算法
8Qi83 小时前
LeetCode 516:最长回文子序列
算法·leetcode·职场和发展·动态规划
mONESY4 小时前
JavaScript 栈、队列、数组与链表核心知识点总结
javascript·面试
贺国亚4 小时前
电商AI辅助交易场景
面试
youngerwang4 小时前
【从搬运工到协处理器:网卡芯片架构、算法、验证与边缘演进深度剖析】
网络·算法·架构·芯片
chase_my_dream4 小时前
C++ + SLAM 高频面试问题整理
开发语言·c++·面试