二叉树题目:好叶子结点对的数量

文章目录

  • 题目
    • 标题和出处
    • 难度
    • 题目描述
      • 要求
      • 示例
      • 数据范围
  • 解法
    • 思路和算法
    • 代码
    • 复杂度分析

题目

标题和出处

标题:好叶子结点对的数量

出处:1530. 好叶子结点对的数量

难度

6 级

题目描述

要求

给定二叉树的根结点 root \texttt{root} root 和整数 distance \texttt{distance} distance。如果二叉树中两个不同的结点之间的最短路径长度小于或者等于 distance \texttt{distance} distance,那它们构成一组好叶子结点对。

返回树中好叶子结点对的数量。

示例

示例 1:

示例 1

输入: root   =   [1,2,3,null,4],   distance   =   3 \texttt{root = [1,2,3,null,4], distance = 3} root = [1,2,3,null,4], distance = 3
输出: 1 \texttt{1} 1
解释:树的叶结点是 3 \texttt{3} 3 4 \texttt{4} 4,它们之间的最短路径的长度是 3 \texttt{3} 3。这是唯一的好叶子结点对。

示例 2:

示例 2

输入: root   =   [1,2,3,4,5,6,7],   distance   =   3 \texttt{root = [1,2,3,4,5,6,7], distance = 3} root = [1,2,3,4,5,6,7], distance = 3
输出: 2 \texttt{2} 2
解释:好叶子结点对为 [4,5] \texttt{[4,5]} [4,5] [6,7] \texttt{[6,7]} [6,7],最短路径长度都是 2 \texttt{2} 2。但是叶子结点对 [4,6] \texttt{[4,6]} [4,6] 不满足要求,因为它们之间的最短路径长度是 4 \texttt{4} 4

示例 3:

输入: root   =   [7,1,4,6,null,5,3,null,null,null,null,null,2],   distance   =   3 \texttt{root = [7,1,4,6,null,5,3,null,null,null,null,null,2], distance = 3} root = [7,1,4,6,null,5,3,null,null,null,null,null,2], distance = 3
输出: 1 \texttt{1} 1
解释:唯一的好叶子结点对是 [2,5] \texttt{[2,5]} [2,5]

数据范围

  • 树中结点数目在范围 [1,   2 10 ] \texttt{[1, 2}^\texttt{10}\texttt{]} [1, 210]
  • 1 ≤ Node.val ≤ 100 \texttt{1} \le \texttt{Node.val} \le \texttt{100} 1Node.val100
  • 1 ≤ distance ≤ 10 \texttt{1} \le \texttt{distance} \le \texttt{10} 1distance10

解法

思路和算法

对于二叉树中的任意两个不同的叶结点,这两个叶结点之间的最短路径是唯一的,且一定经过最近公共祖先。对于每个结点,如果其左子树和右子树都非空,则在其左子树和右子树中各选一个叶结点,这两个叶结点的最近公共祖先即为当前结点,当前结点和两个叶结点的距离之和即为两个叶结点之间的最短路径长度。

为了计算好叶结点对的数量,需要对每个结点计算以当前结点为根结点的子树中的每个叶结点和当前结点的距离,并使用列表存储这些距离。由于好叶结点对满足最短路径长度不超过 distance \textit{distance} distance,因此列表中只需要存储不超过 distance \textit{distance} distance 的距离。可以使用深度优先搜索计算子树中每个叶结点和子树根结点的距离,具体做法如下。

  • 如果当前结点为空,则不存在叶结点,返回空列表。

  • 如果当前结点的左子结点和右子结点都为空,则当前结点为叶结点,叶结点和当前结点的距离为 0 0 0,在列表中添加元素 0 0 0 之后返回列表。

  • 对于其余情况,首先对左子树和右子树分别得到距离列表,对于每个非空子树的距离列表,其中的每个距离加 1 1 1 之后的结果即为叶结点到当前结点的距离,因此将每个非空子树的距离列表中的距离加 1 1 1 之后的值添加到当前结点的距离列表,然后返回列表。

在对每个结点计算子树中每个叶结点和子树根结点的距离的同时,即可计算好叶结点对的数量。如果一个结点的左子树和右子树都不为空,则遍历左子树和右子树的距离列表,并分别计算左子树和右子树中的每对叶结点之间的最短路径长度(同一对叶结点必须分别属于左子树和右子树)。如果一对叶结点之间的最短路径长度不超过 distance \textit{distance} distance,则将好叶结点对的数量加 1 1 1

遍历结束之后,即可得到二叉树中的好叶结点对的数量。

代码

class Solution {
    int pairs = 0;

    public int countPairs(TreeNode root, int distance) {
        getDistances(root, distance);
        return pairs;
    }

    public List<Integer> getDistances(TreeNode node, int distance) {
        List<Integer> distances = new ArrayList<Integer>();
        if (node == null) {
            return distances;
        }
        if (node.left == null && node.right == null) {
            distances.add(0);
            return distances;
        }
        List<Integer> leftDistances = getDistances(node.left, distance);
        List<Integer> rightDistances = getDistances(node.right, distance);
        int leftSize = leftDistances.size();
        int rightSize = rightDistances.size();
        for (int i = 0; i < leftSize; i++) {
            int leftDistance = leftDistances.get(i) + 1;
            leftDistances.set(i, leftDistance);
            if (leftDistance <= distance) {
                distances.add(leftDistance);
            }
        }
        for (int i = 0; i < rightSize; i++) {
            int rightDistance = rightDistances.get(i) + 1;
            rightDistances.set(i, rightDistance);
            if (rightDistance <= distance) {
                distances.add(rightDistance);
            }
        }
        for (int leftDistance : leftDistances) {
            for (int rightDistance : rightDistances) {
                if (leftDistance + rightDistance <= distance) {
                    pairs++;
                }
            }
        }
        return distances;
    }
}

复杂度分析

  • 时间复杂度: O ( n 2 ) O(n^2) O(n2),其中 n n n 是二叉树的结点数。每个结点都被访问一次,对于每一对叶结点都需要计算最短路径长度。

  • 空间复杂度: O ( n ) O(n) O(n),其中 n n n 是二叉树的结点数。空间复杂度主要是存储距离的列表和递归调用的栈空间。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/302177.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

LIN总线与CAN总线的传输方式有什么不同?

​ 关注菲益科公众号—>对话窗口发送 “CANoe ”或“INCA”&#xff0c;即可获得canoe入门到精通电子书和INCA软件安装包&#xff08;不带授权码&#xff09;下载地址。 LIN&#xff0c;Interconnect Network&#xff0c;适用于速度和可靠性要求不高、低成本的场合&#xff…

TS 36.211 V12.0.0-通用功能

本文的内容主要涉及TS 36.211&#xff0c;版本是C00&#xff0c;也就是V12.0.0。

【cmu15445c++入门】(2)c++中的std::move() 左值引用右值引用

左值右值 要理解move语义&#xff0c;必须理解左值和右值的概念。左值的简化定义是左值是对象&#xff0c;指向内存中某个位置。右值是左值之外的任何。 std::move() move语义&#xff0c;在C中是一个有用的方法&#xff0c;它允许在对象之间高效和优化地转移数据所有权。m…

计算机创新协会冬令营——暴力枚举题目06

我给大家第一阶段的最后一道题就到这里了&#xff0c;下次得过段时间了。所以这道题简单一点。但是足够经典 下述题目描述和示例均来自力扣&#xff1a;两数之和 题目描述 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target …

基于SpringBoot微信小程序的宠物美容预约系统设计与实现

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行交流合作✌ 主要内容&#xff1a;SpringBoot、Vue、SSM、HLM…

学校服务器安装anaconda并配置pytorch环境

学校服务器安装anaconda并配置pytorch环境 1.下载Anaconda2.传到xftp中3.在终端运行脚本命令4.安装pytorch4.1 查看cuda版本4.2 创建自己的环境4.3 下载pytorch4.4 验证pytorch是否安装成功 参考视频&#xff1a;远程服务器安装anaconda并配置pytorch环境 使用服务器运行项目&a…

Kafka(五)生产者

目录 Kafka生产者1 配置生产者bootstrap.serverskey.serializervalue.serializerclient.id""acksallbuffer.memory33554432(32MB)compression.typenonebatch.size16384(16KB)max.in.flight.requests.per.connection5max.request.size1048576(1MB)receive.buffer.byte…

UE5.1报错 | C2628: “SNormalDistributionWidget”后面接“void”是非法的(是否忘记了“;”?)

UE5.1报错 | C2628: “SNormalDistributionWidget”后面接“void”是非法的(是否忘记了“;”?) 报错&#xff1a; UE5.1报错 | C2628: “SNormalDistributionWidget”后面接“void”是非法的(是否忘记了“;”?) 解决&#xff1a; 检查定义类的时候&#xff0c;反花括号“…

[每周一更]-(第82期):选购NAS中重要角色RAID

网络附加存储&#xff08;NAS&#xff09;在现代数字生活中扮演着至关重要的角色&#xff0c;而对于NAS的选择中&#xff0c;关注RAID的重要性更是不可忽视的。 数据存储和安全越来越受关注&#xff1b; 为什么要使用NAS&#xff1f; 集中式存储&#xff1a; NAS提供了一个集中…

利用Python实现每日新闻早报推送

本文将介绍如何使用Python编写简单的逻辑&#xff0c;通过调用API接口实现每日新闻推送功能。 步骤&#xff1a; 导入所需的库&#xff1a; 在代码的开头&#xff0c;我们需要导入所需的库。通常&#xff0c;我们会使用requests库来发送HTTP请求&#xff0c;以获取新闻数据。 …

全栈自动化测试面试题含答案和学习路线(适合各级软件测试人员)

在面试战场上&#xff0c;我们需要像忍者一样灵活&#xff0c;像侦探一样聪明&#xff0c;还要像无敌铁金刚一样坚定。只有掌握了这些技巧&#xff0c;我们才能在面试的舞台上闪耀光芒&#xff0c;成为那个令HR们心动的测试人 前言&#xff1a; 我相信大多测试开发的或多或少经…

用户管理第2节课--idea 2023.2 后端--实现基本数据库操作(操作user表) -- 自动生成 --合并生成后的代码【鱼皮】

一、模块页面功能 1.1 domain 【实体对象】 1.2 mapper 【操作数据库的对象】--> UserMapper 1&#xff09;UserMapper 其实就是我们用来操作数据库的一个对象 2) 继承了mybatis- plus&#xff0c;它会自动帮我们去定义一些增删改查的方法。 继承可以看下图&#xf…

数据结构线性表之顺序表

一、线性表及顺序表概念 1.线性表的概念&#xff1b; 线性表是零个或多个具有相同特性的数据元素组成的有限序列&#xff0c;线性表是实际中&#xff0c;广泛使用的一种数据结构&#xff0c;相关的有&#xff1a;顺序表&#xff0c;链表&#xff0c;栈&#xff0c;队列&#…

Python私有变量的定义与访问

class Student():def __init__(self, name, age):self.name nameself.age ageself.__score 0def marking(self, score):if score < 0:return 分数不能为0self.__score scoreprint(self.name 同学本次得分是: str(self.__score)) def __talk(self): # 私有的类可通过在…

如果你创业总失败,不妨看看爷叔是如何创业的!未来三年最大创业风口,2024普通人怎么创业

自从央视点评《繁花》“剧”有强调之后&#xff0c;该电视剧的播放量就节节高升。同时&#xff0c;剧中精彩的商业的大战让人们直呼过瘾&#xff0c;其中的爷叔准确的商业眼光&#xff0c;经典的商业理论也让许多创业者得到了启示。 一、爷叔创业语录 1、做生意要讲究“派头、…

目标检测-One Stage-CenterNet

文章目录 前言一、CenterNet的网络结构和流程二、CenterNet的创新点总结 前言 前文提到的YOLOv3、YOLOv4、YOLOv5都是基于Anchor的算法&#xff08;anchor-based&#xff09;&#xff0c;这类算法有如下缺点&#xff1a; 产生大量的预测框&#xff0c;计算量大正负样本不平衡…

80/20法则-扫盲和复习篇

80/20法则-扫盲和复习篇 一、80/20法则二、对于目标三、时间管理应用四、“二八定律”基本内容总结 一、80/20法则 “80/20法则”是20世纪初意大利统计学家、经济学家维尔弗雷多帕累托提出的&#xff0c;他指出&#xff1a;在任何特定群体中&#xff0c;重要的因子通常只占少数…

js逆向第14例:猿人学第7题动态字体,随风漂移

任务7:采集这5页中胜点列的数据,找出胜点最高的召唤师,将召唤师姓名填入答案中 此题采集的是胜点列表的数据如下 通过控制台审查元素查看,可以看到是乱码,记得几年前的快手,小红书,抖音也采用了此类反爬措施,html页面显示的是乱码,浏览器能正常显示数据,大概率就是…

Spark---RDD算子(单值类型转换算子)

文章目录 1.RDD算子介绍2.转换算子2.1 Value类型2.1.1 map2.1.2 mapPartitions2.1.3 mapPartitionsWithIndex2.1.4 flatMap2.1.5 glom2.1.6 groupBy2.1.7 filter2.1.8 sample2.1.9 distinct2.1.10 coalesce2.1.11 repartition2.1.12 sortBy 1.RDD算子介绍 RDD算子是用于对RDD进…

ElasticSearch 集群搭建与状态监控cerebro

单机的elasticsearch做数据存储&#xff0c;必然面临两个问题:海量数据存储问题、单点故障问题。为了解决存储能力上上限问题就可以用到集群部署。 海量数据存储问题:将索引库从逻辑上拆分为N个分片(shard)&#xff0c;存储到多个节点单点故障问题:将分片数据在不同节点备份 (r…