二叉树 — 返回最大的二叉搜索子树大小

这篇具有很好参考价值的文章主要介绍了二叉树 — 返回最大的二叉搜索子树大小。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

题目:
给定一棵二叉树的head节点,返回这颗二叉树中最大的二叉搜索子树的大小。
一颗二叉树来讲,可能整棵树不是搜索二叉树,但子树是一颗搜索二叉树。如下图所示,这时要返回这颗子搜索二叉树的最大节点个数。下图中,最大的二叉搜索子树大小为:3(5 -> 1 -> 7)。
二叉树 — 返回最大的二叉搜索子树大小,leetCode,算法,算法,java,二叉树
子树的概念是:每个单独节点算一棵子树, 5 -> 1 -> 7三个节点算一棵子树(不可以舍弃任何一个)
1 -> 5 -> 7 -> 6 -> 2同样也算一棵子树,同样不可以舍弃任何一个节点。

递归方式

  1. 只有左树满足二叉搜索树的情况
  2. 只有右树满足二叉搜索树的情况
  3. 整棵树都是二叉搜索树的情况
  4. 判断是否是二叉搜索树需要左右子树max、min的值和当前值节点值进行比较,如果左树最大值小于当前值,右树最小值大于当前值,则说明是一颗二叉搜索树
  5. 需要整棵树的节点数变量(allSize)和满足子树最大二叉搜索树节点数变量(maxBSTSubtreeSize),如果两个值相等,说明是二叉搜索树,如果不相等,则说明不是(用这两个值在构建Info信息类时,可省略一个bollean isBST的变量)。
  6. 根据4、5的要求构建Info对象,递归调用并收集左右子节点的Info信息进行判断。

代码:
Info类用于收集树的信息,并通过递归返回给上层,供上层调用进行分析。

public static class Info{
        int max;
        int min;
        int allSize;
        //满足子树是二叉搜索树最大节点个数
        int maxBSTSubtreeSize;

        public Info(int maxBSTSubtreeSize,int allSize,int max,int min){
            this.maxBSTSubtreeSize = maxBSTSubtreeSize;
            this.allSize = allSize;
            this.max = max;
            this.min = min;
        }
    }
public static int largestBSTSubtree(Node head){
        if(head == null){
            return 0;
        }

        return process(head).maxBSTSubtreeSize;
    }

     //       6
    //    2      7
    // 1    5
    public static Info process(Node head){
        //如果节点为null,不方便构建Info对象信息,所以返回null,下面要对Info对象进行非null判断。
        if (head == null){
            return null;
        }

        Info leftInfo = process(head.left);
        Info rightInfo = process(head.right);

        int max = head.val;
        int min = head.val;
        int allSize = 1;

        if (leftInfo != null){
            max = Math.max(max,leftInfo.max);
            min = Math.min(min,leftInfo.min);
            allSize += leftInfo.allSize;
        }

        if (rightInfo != null){
            max = Math.max(max,rightInfo.max);
            min = Math.min(min,rightInfo.min);
            allSize += rightInfo.allSize;
        }
        //p为每棵树的满足二叉搜索树的节点个数。
        
        //如果左子树不为null,则修改 p1 为 左子树的最大二叉搜索树的个数
        int p1 = -1;
        if (leftInfo != null){
            p1 = leftInfo.maxBSTSubtreeSize;
        }

        //如果右树不为null, 则修改 p2 为 右子树的最大二叉搜索树的个数
        int p2 = -1;
        if (rightInfo != null){
            p2 = rightInfo.maxBSTSubtreeSize;
        }
        
        //只有在左右子树都满足是二叉搜索树的情况下,才更新p3。
        int p3 = -1;
        //左右子树的最大二叉搜索树的个数 = 左右子树整棵树的个数,则说明为二叉搜索树。
        //如果maxBSTSubtreeSize != allSize 则说明之前遍历左右树过程中,出现了 左树最大值 > 当前节点 或 右树最小值 < 当前节点的情况
        boolean isBSTLeft = leftInfo == null ? true : (leftInfo.maxBSTSubtreeSize == leftInfo.allSize);
        boolean isSBTRight = rightInfo == null ? true : (rightInfo.maxBSTSubtreeSize == rightInfo.allSize);

        if (isBSTLeft && isSBTRight){
            //看左子树的最大值 是否小于当前树的值
            //看右子树的最小值 是否小于当前数的值
            boolean leftMaxLessX = leftInfo == null ? true : (leftInfo.max < head.val);
            boolean rightMinMoreX = rightInfo == null ? true : (rightInfo.min > head.val);
			//只有在左右子节点都是二叉搜索树的情况下,更新p3.
            if (leftMaxLessX &&  rightMinMoreX){
                int leftSize = leftInfo == null ? 0 : leftInfo.allSize;
                int rightSize = rightInfo == null ? 0 : rightInfo.allSize;
                p3 = leftSize + rightSize + 1;
            }
        }
        return new Info(Math.max(p3,Math.max(p1,p2)),allSize,max,min);
    }

暴力方式

  1. 将生成的二叉树进行中序遍历(左、头、右)并放进List或Array中
  2. 遍历集合,如果集合中的元素依次都是有小到大的顺序,那说明整棵树都是二叉搜索树(左节点最大值 < 头节点 < 右节点最小值),那直接return 集合的大小。
  3. 如果不满足依次由小到大的顺序,则递归,左右子树找到满足条件的二叉搜索树,并通过Max.math选择较大的一个。

代码

 private static void in(Node head, List<Node> list) {
        if (head == null) {
            return;
        }
        in(head.left, list);
        list.add(head);
        in(head.right, list);
    }
    
private static int largestBSTSubtree1(Node head) {
        if (head == null) {
            return 0;
        }
        List<Node> list = new ArrayList<>();
        //中序遍历
        in(head, list);
        for (int i = 1; i < list.size(); i++) {
            if (list.get(i).val <= list.get(i - 1).val) {
               int leftRes =  largestBSTSubtree1(head.left);
               int rightRes =  largestBSTSubtree1(head.right);
               return Math.max(leftRes,rightRes);
            }
        }
        return list.size();
    }

对数器
递归生成随机二叉树

public static Node generateRandomNode(int maxLength, int maxValue) {
        return generateNode(1, maxLength, maxValue);
    }

    public static Node generateNode(int level, int maxLength, int maxValue) {
        if (level > maxLength || Math.random() < 0.5) {
            return null;
        }
        Node head = new Node((int) (Math.random() * maxValue));
        head.left = generateNode(level + 1, maxLength, maxValue);
        head.right = generateNode(level + 1, maxLength, maxValue);
        return head;
    }

测试文章来源地址https://www.toymoban.com/news/detail-534067.html

 public static void main(String[] args) {
 		//通过大样本数据量进行测试,如果i1 != i2说明有问题,
        int maxValue = 100;
        int maxLength = 50;
        int testNum = 100000;
        for (int i = 0; i < testNum; i++) {
            Node head = generateRandomNode(maxLength, maxValue);
            int i1 = largestBSTSubtree1(head);
            int i2 = largestBSTSubtree2(head);
            if (i1 != i2){
                System.out.println("Fucking Fuck!!!");
                break;
            }
        }
        System.out.println("finish");
    }

到了这里,关于二叉树 — 返回最大的二叉搜索子树大小的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Leetcode】相同的树、对称二叉树、另一颗树的子树

    目录 💡相同的树 题目描述 思路: 代码: 💡对称二叉树 题目描述 思路: 代码: 💡另一棵树的子树 题目描述 思路: 代码: 💡总结   给你两棵二叉树的根节点  p  和  q  ,编写一个函数来检验这两棵树是否相同。 如果两个树在结构上相同,并且节点具有相同的值,则

    2024年02月04日
    浏览(32)
  • 二叉树(下)+Leetcode每日一题——“数据结构与算法”“对称二叉树”“另一棵树的子树”“二叉树的前中后序遍历”

    各位CSDN的uu们你们好呀,今天小雅兰的内容仍然是二叉树和Leetcode每日一题,下面,就让我们进入二叉树的世界吧!!! 这个题目需要重新定义一个函数,函数参数需要有左子树和右子树,题目所给定的函数无法解决问题。 每个不为空的结点,都可以认为是一棵子树的根 

    2024年02月16日
    浏览(33)
  • leetcode 823 带因子的二叉树

    用动态规划 如果两个节点值不同,要乘2,因为两个节点可以互换位置 dp[i] = dp[left] * dp[right] * 2 如果相同 dp[i] = dp[left] * dp[right]

    2024年02月11日
    浏览(26)
  • 【C++干货铺】会搜索的二叉树(BSTree)

    ========================================================================= 个人主页点击直达: 小白不是程序媛 C++系列专栏: C++干货铺 代码仓库: Gitee ========================================================================= 目录 前言: 二叉搜索树 二叉搜索树概念 二叉搜索树操作 二叉搜索树的查找  二叉

    2024年02月04日
    浏览(45)
  • 2023-08-29 LeetCode(带因子的二叉树)

    点击跳转到题目位置 给出一个含有不重复整数元素的数组 arr ,每个整数 arr[i] 均大于 1。 用这些整数来构建二叉树,每个整数可以使用任意次数。其中:每个非叶结点的值应等于它的两个子结点的值的乘积。 满足条件的二叉树一共有多少个?答案可能很大,返回 对 109 + 7

    2024年02月10日
    浏览(77)
  • ​LeetCode解法汇总823. 带因子的二叉树

    https://github.com/September26/java-algorithms 给出一个含有不重复整数元素的数组  arr  ,每个整数  arr[i]  均大于 1。 用这些整数来构建二叉树,每个整数可以使用任意次数。其中:每个非叶结点的值应等于它的两个子结点的值的乘积。 满足条件的二叉树一共有多少个?答案可能很

    2024年02月10日
    浏览(26)
  • 【C++练级之路】【Lv.14】二叉搜索树(进化的二叉树——BST)

    快乐的流畅:个人主页 个人专栏:《C语言》《数据结构世界》《进击的C++》 远方有一堆篝火,在为久候之人燃烧! 二叉树在之前的数据结构章节讲解过,当时使用C来实现。而如今学习的二叉搜索树,便是二叉树的进阶,也更适合使用C++来实现。 二叉搜索树(BST,Binary Se

    2024年03月23日
    浏览(27)
  • leetcode: 1261: 在受污染的二叉树中查找元素

    给出一个满足下述规则的二叉树: root.val == 0 如果  treeNode.val == x  且  treeNode.left != null ,那么  treeNode.left.val == 2 * x + 1 如果  treeNode.val == x  且  treeNode.right != null ,那么  treeNode.right.val == 2 * x + 2 现在这个二叉树受到「污染」,所有的  treeNode.val  都变成了  -1 。 请你先

    2024年03月12日
    浏览(27)
  • 【LeetCode - 每日一题】823. 带因子的二叉树 (2023.08.29)

    元素都大于1,元素不重复。 计数满足要求的二叉树(每个非叶结点的值应等于它的两个子结点的值的乘积)的数量。 元素可以重复使用。 自上而下动态规划。 所有元素大于1,所以不会有 自己×自己=自己 的情况; 元素本身就是一棵二叉树,所以将 dp 初始化为全 1; 将数组

    2024年02月10日
    浏览(28)
  • leetcode 823. 带因子的二叉树(dp+双指针+Long类型)

    题目表述 给出一个含有不重复整数元素的数组 arr ,每个整数 arr[i] 均大于 1。 用这些整数来构建二叉树,每个整数可以使用任意次数。其中:每个非叶结点的值应等于它的两个子结点的值的乘积。 满足条件的二叉树一共有多少个?答案可能很大,返回 对 1 0 9 + 7 10^9+7 1 0 9

    2024年02月10日
    浏览(29)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包