【二叉树】常见题目解析(2)

题目1:104. 二叉树的最大深度 - 力扣(LeetCode)

题目1描述:

题目1分析及解决:

        (1)base case:当前节点为null时,以当前节点为根节点的树最大深度是0。

        (2)节点不为null时,节点应该统计左右子树的最大深度,并在其中取一个最大值 + 1即可得到以当前节点为根节点的树最大深度是多少(+ 1是因为当前节点也算一个深度)。

        (3)既然要用到左右子树的递归结果,那么肯定是后序遍历整颗树。

        Code:

class Solution {public int maxDepth(TreeNode root) {//空树最大深度为0if(root == null)return 0;//获取左右子树的最大深度int leftDepth = maxDepth(root.left);int rightDepth = maxDepth(root.right);//在左右子树的结果中选一个较大值 + 1(当前节点也算一个深度)return Math.max(leftDepth,rightDepth) + 1;}
}

题目2:111. 二叉树的最小深度 - 力扣(LeetCode)

题目2描述:

题目2分析与解决:

        (1)base case:当前节点为null时,最小深度是0;当节点的左、右子节点都为null时,说明当前节点是叶子节点,最小深度是1.

        (2)节点不为null时,如果当前节点的左节点不为null,就获取左节点的最小深度;如果当前节点的右节点不为null,就获取右节点的最小深度;最后在左、右子节点返回的结果中选一个较小值 + 1即可得到以当前节点为根节点的树最小深度是多少。

        (3)由于还是要获取左、右子节点的返回结果,所以仍然是后序遍历。为什么要在左、右子节点不为null时,才能去递归获取他们的最小深度呢?看下图

        总结:不加if判断会被空节点影响最终结果。

        Code:

class Solution {public int minDepth(TreeNode root) {//节点为null时,最小深度是0if(root == null)return 0;//节点为叶子节点时,最小深度是1if(root.left == null && root.right == null)return 1;int leftDepth = Integer.MAX_VALUE;int rightDepth = Integer.MAX_VALUE;if(root.left != null)leftDepth = minDepth(root.left);if(root.right != null)rightDepth = minDepth(root.right);return Math.min(leftDepth,rightDepth) + 1;}
}

题目3:958. 二叉树的完全性检验 - 力扣(LeetCode)

题目3描述:

题目3分析与解决:

        (1)完全二叉树的特点如下图所示:

        (2)逐层遍历每一个节点(bfs),当一个节点的左子节点为null而右子节点不为null时,说明不是完全二叉树。

        (3)当遍历到一个节点,它的左、右子结点有一个为null,若后续节点不是叶子节点,说明不是完全二叉树。如下图所示,遍历到a节点时,其左子节点不为null、右子节点为null;后面遍历b节点时,如果b是叶子节点,则不破坏完全二叉树的性质,如果b不是叶子节点,则中间有空缺,不符合完全二叉树的定义。

        Code:

class Solution {//题目规定节点个数在100以内public static int MAX = 101;    //用数组模拟队列public static TreeNode [] queue = new TreeNode[MAX];//用head、tail两个变量维护队列的长度及出入队顺序public static int head,tail;public boolean isCompleteTree(TreeNode root) {//空树也是完全二叉树if(root == null)return true;//初始队列大小为0head = tail = 0;//根节点入队queue[tail++] = root;//标记变量:遍历到一个节点,只要它的左、右子节点有一个为null,就设置为trueboolean flag = false;//队列不为空while(head < tail){//弹出队头节点TreeNode node = queue[head++];//返回false的两个条件,满足一个即可//1.左子节点为null的同时右子节点不为null//2.有节点设置flag为true的同时当前节点不是叶子节点if((node.left == null && node.right != null) ||(flag && (node.left != null || node.right != null)))return false;if(node.left != null)queue[tail++] = node.left;if(node.right != null)queue[tail++] = node.right;if(node.left == null || node.right == null)flag = true;}//如果逐层遍历过程中没有返回false,那么这棵树是完全二叉树,返回truereturn true;}
}

题目4:222. 完全二叉树的节点个数 - 力扣(LeetCode)

题目4描述:

题目4分析与解决:

        (1)最基本的思路是:递归左、右子树获取他们的节点个数,当递归到叶子节点时,就返回1(叶子节点的左、右子节点都为null),每层节点收集左、右子树的递归结果再 + 1(当前结点也算一个结点)返回即可。

        (2)基于上述思路无论是什么类型的二叉树都能统计其结点个数,但题目强调了是一颗完全二叉树,我们该如何利用这一性质?根据题目3我们知道,一颗完全二叉树不一定是一颗满二叉树,但它一部分的子树一定是一颗满二叉树;利用这一性质,当我们发现以当前结点为根节点的树是满二叉树时,直接计算结点个数返回,无需获取左、右子树的递归结果,减少时间复杂度

        (3)一颗满二叉树的结点个数如何计算呢? 不就是2^层数 - 1吗? 所以当我们递归到一个结点时,我们首先判断它是否是一颗满二叉树,是则直接计算结点个数;不是,则递归左、右子树,获取左、右子树的递归结果,再+1即可。

        Code:

class Solution {public int countNodes(TreeNode root) {//空结点肯定不算一个结点if(root == null)return 0;TreeNode l = root.left;int leftDepth = 0;//一直往左树遍历,看最深是多少while(l != null){l = l.left;leftDepth++;}TreeNode r = root.right;int rightDepth = 0;//一直往右树遍历,看最深是多少while(r != null){r = r.right;rightDepth++;}//如果左、右子树的深度相同//说明以当前结点为根节点的树是一颗满二叉树,直接计算结点个数并返回if(leftDepth == rightDepth)return (2 << leftDepth) - 1;else//否则获取左、右子树的递归结果 + 1 返回return countNodes(root.left) + countNodes(root.right) + 1;}
}

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Linux】24、文件系统、磁盘 IO

文章目录 一、文件系统1.1 索引节点和目录项1.2 虚拟文件系统 VFS1.3 文件系统 I/O1.5 性能观测1.5.1 容量1.5.2 缓存1.5.3 find 命令的缓存 二、磁盘 I/O2.1 通用块层2.2 I/O 栈2.3 磁盘性能指标2.3.1 磁盘 I/O 观测2.3.2 进程 I/O 观测 2.4 案例&#xff1a;找到打大量日志的…

深入解析SpringBoot的请求响应机制

SpringBootWeb请求响应 前言1. 请求1.1 Postman介绍 1.2 简单参数1.2.1 原始方式1.2.2 SpringBoot方式1.2.3 参数名不一致 1.3 实体参数1.3.1 简单实体对象1.3.2 复杂实体对象 1.4 数组集合参数1.4.1 数组1.4.2 集合 1.5 日期参数1.6 JSON参数1.7 路径参数 2. 响应2.1 Response…

uniapp是否可以用elementUI等前端UI库、使用步骤以及需要注意的问题

文章目录 uniapp是否可以用elementUI等前端UI库使用方法和步骤问题如何解决 uniapp是否可以用elementUI等前端UI库 在PC端开发uniapp&#xff0c;可以用elementUI&#xff0c;因为elementUI就是PC端的。 在使用uniapp&#xff0c;选择vue2.0时&#xff0c;实测可以用nodejs16的…

小米智能摄像头mp4多碎片手工恢复案例

小米智能摄像头mp4多碎片手工恢复案例 智能摄像头目前在市场上极为常见&#xff0c;仅需要一张存储卡即可实现视频、音频的采集&#xff0c;同时可以通过手机APP进行远程控制&#xff0c;相比传统安防品牌成本更低、更容易部署。在智能摄像头品牌中小米算是绝对的大厂&#xf…

黑马一站制造数仓实战1

1. 项目目标 一站制造 企业中项目开发的落地&#xff1a;代码开发 代码开发&#xff1a;SQL【DSL SQL】 SparkCore SparkSQL 数仓的一些实际应用&#xff1a;分层体系、建模实现 2. 内容目标 项目业务介绍&#xff1a;背景、需求 项目技术架构&#xff1a;选型、架构 项目环境…

堆排序算法

我们之前学了堆&#xff1a; 数据结构---堆-CSDN博客 数据结构&#xff1a;堆的实现-CSDN博客 我们知道堆有小堆和大堆之分&#xff0c;根节点不是最小就是最大的&#xff0c;我们可以利用这个特点实现堆排序 思路&#xff1a; 为什么我们要选择堆排序呢 它的效率相比于冒泡…

Nginx反向代理详解

Nginx反向代理详解 nginx反向代理是一种常用的服务器架构设计方案&#xff0c;其原理是将客户端请求先发送到反向代理服务器&#xff0c;反向代理服务器再将请求转发到后端真实服务器处理&#xff0c;并将处理结果返回给客户端&#xff0c;从而实现负载均衡、高可用、安全和减…

数据结构:带头双向循环链表的实现

引言 单链表存在缺陷&#xff1a;需要从头开始找前一个节点 解决方法&#xff1a;双向链表 链表的结构&#xff08;8种&#xff09;&#xff1a; 1. 单向&#xff0c;双向 2. 带头、不带头 带头即为带哨兵位的头节点&#xff0c;第一个节点不存储有效数据。带头节点&#…

C#,数值计算——插值和外推,谢别德(Shep)插值方法的计算方法与源程序

1 文本格式 using System; namespace Legalsoft.Truffer { /// <summary> /// 谢别德插值方法 /// Object for Shepard interpolation using n points in dim dimensions. Call /// constructor once, then interp as many times as desired. /// &…

【网络奇幻之旅】那年我与大数据的邂逅

&#x1f33a;个人主页&#xff1a;Dawn黎明开始 &#x1f380;系列专栏&#xff1a;网络奇幻之旅 ⭐每日一句&#xff1a;循梦而行&#xff0c;向阳而生 &#x1f4e2;欢迎大家&#xff1a;关注&#x1f50d;点赞&#x1f44d;评论&#x1f4dd;收藏⭐️ 文章目录 &#x1f4…

如何删除mac苹果电脑上面的流氓软件?

在使用苹果电脑的过程中&#xff0c;有时候我们也会遇到一些不需要的软件。无论是因为不再需要&#xff0c;或者是为了释放磁盘空间&#xff0c;删除这些软件是很重要的。本文将为大家介绍怎样删除苹果电脑上的软件&#xff01; CleanMyMac X全新版下载如下: https://wm.make…

【图论】重庆大学图论与应用课程期末复习资料2-各章考点(计算部分)(私人复习资料)

图论各章考点 二、树1、避圈法&#xff08;克鲁斯克尔算法&#xff09;2、破圈法3、Prim算法 四、路径算法1、Dijkstra算法2、Floyd算法 五、匹配1、匈牙利算法&#xff08;最大权理想匹配&#xff08;最小权权值取反&#xff09;&#xff09; 六、行遍性问题1、Fleury算法&…