代码随想录算法训练营 DAY 16 | 104.二叉树最大深度 111.二叉树最小深度 222.完全二叉树的节点个数

104.二叉树最大深度

深度和高度

  • 二叉树节点的深度:指从根节点到该节点的最长简单路径边的条数或者节点数(取决于深度从0开始还是从1开始)
  • 二叉树节点的高度:指从该节点到叶子节点的最长简单路径边的条数或者节点数(取决于高度从0开始还是从1开始)

前序求的就是深度,用后序求的是高度。

在这里插入图片描述

根节点的深度,其实就是这棵树的最大高度!

  • 整体思路:按照后序遍历左右中的顺序,依次遍历每个节点,把它的高度返回给上一层父节点!最后回到根节点时就掌握了所有节点的高度信息!

递归法

递归三部曲:

  • 确定递归函数返回值和参数
int getHeight(TreeNode node)
  • 确定终止条件:
if(node == null) return 0;
  • 确定单层递归的逻辑

按照后序遍历左 右 中的顺序依次处理。每次返回给父节点(中)的时候 就代表了当前根节点的最大高度!!

int leftHeight = getHeight(node.left);  //左
int rightHeight = getHeight(node.right);  //右
int maxHeight = 1 + Math.max(leftHeight, rightHeight);

在这里插入图片描述

  • java代码
class Solution {public int getHeight(TreeNode node) {  //后序遍历if(node == null) return 0;  //结束条件int leftHeight = getHeight(node.left);  //左int rightHeight = getHeight(node.right);  //右int maxHeight = 1 + Math.max(leftHeight, rightHeight);return maxHeight;}public int maxDepth(TreeNode root) {return getHeight(root);}
}
  • 精简版
class solution {
public int maxDepth(TreeNode root) {if (root == null) return 0;return 1 + Math.Max(maxDepth(root.left), maxDepth(root.right));}
};

559.n叉树的最大深度

把左和右递归遍历的操作放到一个for循环里,遍历node.children 得到depth,最后return depth+1即可!

class Solution {public int getHeight(Node node) {if(node == null) return 0;int depth = 0;for(Node cur : node.children) {depth = Math.max(depth, getHeight(cur));}return 1 + depth;}public int maxDepth(Node root) {return getHeight(root);}
}

111.二叉树最小深度

前序遍历和后序遍历都可以,前序求的是深度,后序求的是高度。这里我们用后序。

明确题目定义!叶子节点是指左右孩子都为null的节点,因此我们在计算depth时就要添加条件判断,分别判断左为空右不为空左不为空右为空左右都不空的情况来计算当前最小深度!

后序遍历是左右中,从最底层开始一层层往上传递到根节点。

在这里插入图片描述

后序 递归

递归三部曲:

  • 确定递归函数返回值和参数
int getHeight(TreeNode node)
  • 确定终止条件:
if(node == null) return 0;
  • 确定单层递归的逻辑

分成三种情况:左为空右不为空左不为空右为空左右都不空。然后return 接收到的最小高度+1

int leftHeight = getHeight(node.left);int rightHeight = getHeight(node.right);if(node.right == null && node.left != null) return 1 + leftHeight;else if(node.left == null && node.right != null) return 1 + rightHeight;else {  //左右都不为空return 1 + Math.min(leftHeight, rightHeight);}
  • java代码
class Solution {int getHeight(TreeNode node) {if(node == null) return 0;int leftHeight = getHeight(node.left);int rightHeight = getHeight(node.right);if(node.right == null && node.left != null) return 1 + leftHeight;else if(node.left == null && node.right != null) return 1 + rightHeight;else {  //左右都不为空return 1 + Math.min(leftHeight, rightHeight);}}public int minDepth(TreeNode root) {return getHeight(root);}
}

222.完全二叉树的节点个数

普通做法

直接把它当成是一棵普通二叉树,遍历的过程中记录节点数量。递归的话还是用后序(左右中)

  • 时间复杂度:O(n)
  • 空间复杂度:O(log n),算上了递归系统栈占用的空间

完全二叉树做法

完全二叉树只有两种情况,情况一:就是满二叉树,情况二:最后一层叶子节点没有满。

对于情况一,可以直接用 2^树深度 - 1 来计算,注意这里根节点深度为1。

对于情况二,分别递归左孩子,和右孩子,递归到某一深度一定会有左孩子或者右孩子为满二叉树,然后依然可以按照情况1来计算。

在这里插入图片描述

我们能不能利用完全二叉树的特性,不要去遍历所有的节点呢?只遍历一部分节点就能判断?

  • 核心思路:利用完全二叉树特性,因为题目是完全二叉树,直接全部遍历左孩子和右孩子,如果高度相等它就是满二叉树,直接return 2^树深度 - 1个节点。内侧的节点就不用遍历了!

  • 在完全二叉树中,如果递归向左遍历的深度等于递归向右遍历的深度,那说明就是满二叉树。

递归三部曲

终止条件:==null或者为满二叉树的情况

 //终止条件if(root == null) return 0;TreeNode left = root.left;TreeNode right = root.right;int leftHeight = 0, rightHeight = 0;  //计数从0开始while(left != null) {left = left.left;leftHeight += 1;} while(right != null) {right = right.right;rightHeight += 1;}if(leftHeight == rightHeight) return (2 << leftHeight) - 1; 
  • 单层递归逻辑
return countNodes(root.left) + countNodes(root.right) + 1;
  • 完整代码
class Solution {public int countNodes(TreeNode root) {//终止条件if(root == null) return 0;TreeNode left = root.left;TreeNode right = root.right;int leftHeight = 0, rightHeight = 0;  //计数从0开始while(left != null) {left = left.left;leftHeight += 1;} while(right != null) {right = right.right;rightHeight += 1;}if(leftHeight == rightHeight) return (2 << leftHeight) - 1; return countNodes(root.left) + countNodes(root.right) + 1;}
}
  • 时间复杂度:O(log n × log n)
  • 空间复杂度:O(log n)

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

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

相关文章

Linux学习:git补充与调试工具gdb

目录 1. git版本控制器&#xff08;续&#xff09;1.1 git本地仓库结构1.2 git实现版本控制与多人协作的方式1.3 git相关指令&#xff0c;多分支模型与.gitignore文件 2. gdb调试工具2.1 企业项目开发流程简述与调试的必要性2.2 bug的调试思路方法与调式工具的使用 1. git版本控…

软考高级:特定领域软件架构(DSSA)概念和例题

作者&#xff1a;明明如月学长&#xff0c; CSDN 博客专家&#xff0c;大厂高级 Java 工程师&#xff0c;《性能优化方法论》作者、《解锁大厂思维&#xff1a;剖析《阿里巴巴Java开发手册》》、《再学经典&#xff1a;《Effective Java》独家解析》专栏作者。 热门文章推荐&am…

linux网络固定ip的方式

1. 注意 默认情况下&#xff0c;我们linux操作系统 ip 获取的方式是自动获取的方式&#xff08;DHCP&#xff09;&#xff0c;自动获取在我们需要进行集群配置的时候&#xff0c;IP会经常变化&#xff0c;需要将IP固定下来。 2. 第一步 编辑我们 linux 的网卡文件 这个网卡文件…

环境变量配置

举一个小例子来演示一下环境变量配置。 在CMD中打开QQ界面&#xff0c;首先需要知道QQ.exe文件的完整路径。一旦有了这个路径&#xff0c;可以按照以下步骤操作&#xff1a; 打开CMD窗口。可以通过按下Windows键R&#xff0c;输入“cmd”并回车来打开它。在CMD窗口中&#xf…

【LINUX笔记】驱动开发框架

应用程序调动驱动程序 驱动模块运行模式 模块加载-卸载 加载卸载注册函数 加载 驱动编译完成以后扩展名为.ko&#xff0c;有两种命令可以加载驱动模块&#xff1a; insmod和modprobe 驱动卸载 驱动注册注销 //查看当前已经被使用掉的设备号 cat /proc/devices 实现设备的具…

按键模拟精灵

按键模拟精灵功能简单&#xff1a; 1.添加模拟按键 2.删除模拟按键 3.开始模拟 4.停止模拟 适合简单的按键操作&#xff0c;有需要的可以点赞收藏关注我&#xff01;

Axure RP 9 for mac中文版密钥激活版下载

Axure RP 9是一款专业的快速原型设计工具&#xff0c;它可以帮助产品设计师、交互设计师和用户体验设计师等创建高保真度、交互性强的原型&#xff0c;以便在产品开发之前进行测试和用户验证。 软件下载&#xff1a;Axure RP 9 for mac中文版密钥激活版下载 该工具具有丰富的功…

javaSwing俄罗斯方块

目录 1 绪论 1.1程序开发背景及意义 1.2开发技术概述 1.3俄罗斯方块游戏的研究现状 1.3.1 国内外研究现状 1.3.2 文献综述 2相关技术 2.4.1 硬件平台&#xff1a; 2.4.2 软件平台&#xff1a; 3 系统分析 3.1可行性分析 3.1.1经济可行性分析 3.1.2技术可行性分析 3.1.3社会可行…

Linux 文件系统:重定向、缓冲区

目录 一、重定向 1、输出重定向 2、输入重定向 3、追加重定向 4、dup2 系统调用 二、理性理解Linux系统下“一切皆文件” 了解硬件接口 三、缓冲区 1、为什么要有缓冲区? 2、刷新策略 3、缓冲模式改变导致发生写时拷贝 未创建子进程时 创建子进程时 使用fflush…

ubuntu將en01變成eth0的形式

文章目录 前言一、操作步驟1、打開grub文件2、輸入更新指令3、查看結果 二、使用步骤总结 前言 一、操作步驟 1、打開grub文件 使用管理員權限打開&#xff0c;添加新內容 sudo gedit grub2、輸入更新指令 sudo update-grub3、查看結果 使用ifconfig查看是否修改成功&…

安达发|印刷包装APS生产计划排产系统的商业价值

在当今快速消费和竞争激烈的市场环境中&#xff0c;印刷包装行业面临着前所未有的挑战。随着客户需求的多样化、交付期限的缩短以及原材料价格的波动&#xff0c;传统的生产管理方法已无法满足现代印刷包装企业的复杂需求。为了保持竞争力&#xff0c;企业必须采用先进的生产计…

接口测试面试题整理

HTTP, HTTPS协议 什么是DNSHTTP协议怎么抓取HTTPS协议说出请求接口中常见的返回状态码http协议请求方式HTTP和HTTPS协议区别HTTP和HTTPS实现机有什么不同POST和GET的区别HTTP请求报文与响应报文格式什么是Http协议无状态协议?怎么解决HTTP协议无状态协议常见的POST提交数据方…

C++进阶02 多态性

听课笔记简单整理&#xff0c;供小伙伴们参考~&#x1f95d;&#x1f95d; 第1版&#xff1a;听课的记录代码~&#x1f9e9;&#x1f9e9; 编辑&#xff1a;梅头脑&#x1f338; 审核&#xff1a;文心一言 目录 &#x1f433;课程来源 &#x1f433;前言 &#x1f40b;运…

JAVA安全(偏基础)

SQL注入 SQLI(SQL Injection)&#xff0c; SQL注入是因为程序未能正确对用户的输入进行检查&#xff0c;将用户的输入以拼接的方式带入SQL语句&#xff0c;导致了SQL注入的产生。攻击者可通过SQL注入直接获取数据库信息&#xff0c;造成信息泄漏。 JDBC JDBC有两个方法获取s…

数据挖掘之关联规则

“啤酒和尿布的荣誉” 概念 项 item&#xff1a;单个的事物个体 &#xff0c;I{i1,i2…im}是所有项的集合&#xff0c;|I|m是项的总数项集&#xff08;item set)/模式&#xff08;pattern)&#xff1a;项的集合&#xff0c;包含k个项的项集称为k-项集数据集(data set)/数据库…

Linux快速入门,上手开发 02.VMware的安装部署

倘若穷途末路&#xff0c;那便势如破竹 —— 24.3.21 一、VMware的作用 在Windows或IOS系统下&#xff0c;给本地电脑安装VMware虚拟机&#xff0c;用来在虚拟机上安装Linux系统&#xff0c;避免重复资源的浪费&#xff0c;可以在虚拟机上搭建Linux系统进行学习 二、VMware的安…

树莓派夜视摄像头拍摄红外LED灯

NoIR相机是一种特殊类型的红外摄像头&#xff0c;其名称来源于"No Infrared"的缩写。与普通的彩色摄像头不同&#xff0c;NoIR相机具备红外摄影和低光条件下摄影的能力。 一般摄像头能够感知可见光&#xff0c;并用于普通摄影和视频拍摄。而NoIR相机则在设计上去除了…

C语言疑难题:杨辉三角形、辗转相除求最大公约数、求π的近似值、兔子问题、打印菱形

杨辉三角形&#xff1a;打印杨辉三角形的前10行 /* 杨辉三角形&#xff1a;打印杨辉三角形的前10行 */ #include<stdio.h> int main(){ int i,j; int a[10][10]; printf("\n"); for(i0;i<10;i){ a[i][0]1; a[i][i]1; …

ROS机器人入门第一课:ROS快速体验——python实现HelloWorld

文章目录 ROS机器人入门第一课&#xff1a;ROS快速体验——python实现HelloWorld一、HelloWorld实现简介&#xff08;一&#xff09;创建工作空间并初始化&#xff08;二&#xff09;进入 src 创建 ros 包并添加依赖 二、HelloWorld(Python版)&#xff08;二&#xff09;进入 r…

Java JDK8新日期API

一、 JDK8 中增加了一套全新的日期时间 API&#xff0c;这套 API 设计合理&#xff0c;是线程安全的。 java.time – 包含值对象的基础包java.time.chrono – 提供对不同的日历系统的访问java.time.format – 格式化和解析时间和日期java.time.temporal – 包括底层框架和扩展…