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

运行结果

相关推荐
日拱一卒——功不唐捐4 小时前
交换排序:冒泡排序和快速排序(C语言)
c语言·数据结构·算法
2301_790300964 小时前
C++与物联网开发
开发语言·c++·算法
山楂树の4 小时前
3D渲染分层机制 Layers 的原理分析(Threejs)
数据结构·3d·相机
鱼跃鹰飞4 小时前
Leetcode会员尊享面试100题:255.验证二叉搜索树的前序遍历序列
算法·leetcode·面试
踩坑记录4 小时前
leetcode hot100 146. LRU 缓存 medium OrderedDict 双向链表 双向字典 哈希表
数据结构·链表
郝学胜-神的一滴5 小时前
机器学习中的特征提取:PCA与LDA详解及sklearn实践
人工智能·python·程序人生·算法·机器学习·sklearn
Dylan的码园5 小时前
深入浅出Java排序:从基础算法到实战优化(下)
java·算法·排序算法
YuTaoShao5 小时前
【LeetCode 每日一题】744. 寻找比目标字母大的最小字母——(解法一)遍历
算法·leetcode·职场和发展
代码无bug抓狂人5 小时前
动态规划习题篇(不同路径和整数拆分)
算法·动态规划