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

运行结果

相关推荐
@小柯555m几秒前
算法(移动零)
数据结构·算法·leetcode
Purple Coder2 分钟前
面试题目总结
面试·职场和发展
小江的记录本2 分钟前
【Java基础】Java 8-21新特性 :JDK17:密封类、模式匹配、Record类(附《思维导图》+《面试高频考点清单》)
java·数据结构·后端·python·mysql·面试·职场和发展
小江的记录本4 分钟前
【Java基础】集合框架: ArrayList vs LinkedList 核心区别、扩容机制(附《思维导图》+《面试高频考点清单》)
java·数据库·python·mysql·spring·面试·maven
Mahir089 分钟前
Spring 核心原理:IoC/DI 与 Bean 生命周期全景解析
java·后端·spring·面试·bean生命周期·控制反转ioc·依赖注入di
重生之我是Java开发战士12 分钟前
【贪心算法】柠檬水找零,将数组和减半的最少操作次数,最大数,摆动序列, 最长递增子序列,递增的三元子序列
算法·贪心算法
Godspeed Zhao13 分钟前
从零开始学AI17——SVM的数学支撑知识
算法·机器学习·支持向量机
我爱cope15 分钟前
【力扣hot100:53. 最大子数组和】
算法·leetcode·职场和发展
枕星而眠17 分钟前
数据结构哈希表(散列表)超详细总结
c语言·数据结构·后端·散列表
一条泥憨鱼17 分钟前
【Java 进阶】LinkedHashMap 与 TreeMap
java·开发语言·数据结构·笔记·后端·学习