二叉树10:二叉树的最小深度

news/2024/10/25 3:54:54/

主要是我自己刷题的一些记录过程。如果有错可以指出哦,大家一起进步。
转载代码随想录
原文链接:
代码随想录
leetcode链接:111. 二叉树的最小深度

题目:

给定一个二叉树,找出其最小深度。

最小深度是从根节点到最近叶子节点的最短路径上的节点数量。
说明:叶子节点是指没有子节点的节点。

示例:

示例 1:

在这里插入图片描述

输入:root = [3,9,20,null,null,15,7]
输出:2

示例 2:

输入:root = [2,null,3,null,4,null,5,null,6]
输出:5

提示:

树中节点数的范围在 [0, 105] 内
-1000 <= Node.val <= 1000

思路:

直觉上好像和求最大深度差不多,其实还是差不少的。

本题依然是前序遍历和后序遍历都可以,前序求的是深度,后序求的是高度。

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

那么使用后序遍历,其实求的是根节点到叶子节点的最小距离,就是求高度的过程,不过这个最小距离 也同样是最小深度。

以下讲解中遍历顺序上依然采用后序遍历(因为要比较递归返回之后的结果,本文我也给出前序遍历的写法)。

本题还有一个误区,在处理节点的过程中,最大深度很容易理解,最小深度就不那么好理解,如图:
在这里插入图片描述
这就重新审题了,题目中说的是:最小深度是从根节点到最近叶子节点的最短路径上的节点数量。,注意是叶子节点。

什么是叶子节点,左右孩子都为空的节点才是叶子节点!

递归法

来来来,一起递归三部曲:

确定递归函数的参数和返回值
参数为要传入的二叉树根节点,返回的是int类型的深度。

代码如下:

int getDepth(TreeNode* node)

确定终止条件
终止条件也是遇到空节点返回0,表示当前节点的高度为0。
代码如下:(其实我感觉这里到叶子节点也可以)

if (node == NULL) return 0;
// if (!node->left&&!node->right) return 1;//这个也可以

确定单层递归的逻辑
这块和求最大深度可就不一样了,一些同学可能会写如下代码:

int leftDepth = getDepth(node->left);
int rightDepth = getDepth(node->right);
int result = 1 + min(leftDepth, rightDepth);
return result;

这个代码就犯了此图中的误区:
在这里插入图片描述

如果这么求的话,没有左孩子的分支会算为最短深度。

所以,如果左子树为空,右子树不为空,说明最小深度是 1 + 右子树的深度。

反之,右子树为空,左子树不为空,最小深度是 1 + 左子树的深度。 最后如果左右子树都不为空,返回左右子树深度最小值 + 1 。

代码如下:

int leftDepth = getDepth(node->left);           // 左
int rightDepth = getDepth(node->right);         // 右// 中
// 当一个左子树为空,右不为空,这时并不是最低点
if (node->left == NULL && node->right != NULL) { return 1 + rightDepth;
}   
// 当一个右子树为空,左不为空,这时并不是最低点
if (node->left != NULL && node->right == NULL) { return 1 + leftDepth;
}
int result = 1 + min(leftDepth, rightDepth);
return result;

遍历的顺序为后序(左右中),可以看出:求二叉树的最小深度和求二叉树的最大深度的差别主要在于处理左右孩子不为空的逻辑。

整体递归代码如下:

class Solution {
public:int getDepth(TreeNode* node) {if (node == NULL) return 0;int leftDepth = getDepth(node->left);           // 左int rightDepth = getDepth(node->right);         // 右// 中// 当一个左子树为空,右不为空,这时并不是最低点if (node->left == NULL && node->right != NULL) { return 1 + rightDepth;}   // 当一个右子树为空,左不为空,这时并不是最低点if (node->left != NULL && node->right == NULL) { return 1 + leftDepth;}int result = 1 + min(leftDepth, rightDepth);return result;}int minDepth(TreeNode* root) {return getDepth(root);}
};

精简之后代码如下:

class Solution {
public:int minDepth(TreeNode* root) {if (root == NULL) return 0;if (root->left == NULL && root->right != NULL) {return 1 + minDepth(root->right);}if (root->left != NULL && root->right == NULL) {return 1 + minDepth(root->left);}return 1 + min(minDepth(root->left), minDepth(root->right));}
};

精简之后的代码根本看不出是哪种遍历方式,所以依然还要强调一波:如果对二叉树的操作还不熟练,尽量不要直接照着精简代码来学。

前序遍历的方式:

class Solution {
private:int result;void getdepth(TreeNode* node, int depth) {if (node->left == NULL && node->right == NULL) {result = min(depth, result);  return;}// 中 只不过中没有处理的逻辑if (node->left) { // 左getdepth(node->left, depth + 1);}if (node->right) { // 右getdepth(node->right, depth + 1);}return ;}public:int minDepth(TreeNode* root) {if (root == NULL) return 0;result = INT_MAX;getdepth(root, 1);return result;}
};

迭代法

相对于104.二叉树的最大深度 (opens new window),本题还可以使用层序遍历的方式来解决,思路是一样的。

需要注意的是,只有当左右孩子都为空的时候,才说明遍历到最低点了。如果其中一个孩子不为空则不是最低点

代码如下:(详细注释)

class Solution {
public:int minDepth(TreeNode* root) {if (root == NULL) return 0;int depth = 0;queue<TreeNode*> que;que.push(root);while(!que.empty()) {int size = que.size();depth++; // 记录最小深度for (int i = 0; i < size; i++) {TreeNode* node = que.front();que.pop();if (node->left) que.push(node->left);if (node->right) que.push(node->right);if (!node->left && !node->right) { // 当左右孩子都为空的时候,说明是最低点的一层了,退出return depth;}}}return depth;}
};

自己的代码

class Solution {
public:int getMinDepth(TreeNode*node){if(!node) return 0;int leftMinDepth,rightMinDepth;if(node->left&&node->right) {leftMinDepth = getMinDepth(node->left);rightMinDepth = getMinDepth(node->right);return 1+min(leftMinDepth,rightMinDepth);}else if(!node->left){return 1+getMinDepth(node->right);}else if(!node->right){return 1+getMinDepth(node->left);}else{  //左右孩子都没有return 1;}}int minDepth(TreeNode* root) {if(!root) return 0;return getMinDepth(root);}
};

http://www.ppmy.cn/news/5790.html

相关文章

Jenkins + Jmeter + Ant 持续集成

搭建提前安装好&#xff1a;ant Jenkins 环境 一、Jenkins 安装 Ant 插件&#xff1a; 进入Jenkins 配置插件页面&#xff0c;安装ant 插件&#xff1a; 打开插件配置页面&#xff0c;如下图&#xff1a; 点击“Available” 在输入框搜索 ant 安装即可&#xff1a; 二、安装…

一、线程相关概念

文章目录相关概念程序(program)进程线程单线程与多线程并发与并行相关概念 程序(program) 是为完成特定任务、用某种语言编写的一组指令的集合。简单的说:就是我们写的代码。 进程 进程是指运行中的程序&#xff0c;比如我们使用QQ&#xff0c;就启动了一个进程&#xff0c…

-防火墙-

数据来源 一、防火墙的基本概念 防火墙的定义&#xff1a;是一款具备安全防护功能网络设备 ◆ 隔离网络 将需要保护的网络与不可信任网络进行隔离&#xff0c;隐藏信息并进行安全防护 防火墙基本功能&#xff1a; ◆ 访问控制 - ACL ◆ 攻击防护 ◆ 冗余设计 ◆ 路由、交…

redis 大key 防坑指南

目录 一、大key危害 二、为什么会引入大key问题 三、举例 四、如何防控 五、发生了大key问题怎么办 六、如何测试阶段暴露大key问题 一、大key危害 redis大key导致redis负载比较高&#xff0c;影响redis的性能 二、为什么会引入大key问题 存入redis数量不可控&#x…

校园文件发布系统|基于Springboot实现校园文章发布系统

作者主页&#xff1a;编程千纸鹤 作者简介&#xff1a;Java、前端、Pythone开发多年&#xff0c;做过高程&#xff0c;项目经理&#xff0c;架构师 主要内容&#xff1a;Java项目开发、毕业设计开发、面试技术整理、最新技术分享 收藏点赞不迷路 关注作者有好处 文末获得源码 …

基于事件触发的二阶多智能体领导跟随一致性

【无限嚣张&#xff08;菜菜&#xff09;】&#xff1a;hello您好&#xff0c;我是菜菜&#xff0c;很高兴您能来访我的博客&#xff0c;我是一名爱好编程学习研究的菜菜&#xff0c;每天分享自己的学习&#xff0c;想法&#xff0c;博客来源与自己的学习项目以及编程中遇到问题…

Node基础——认识Node

什么是Node 首先JavaScript是一门编程语言&#xff0c;就像Java、Python、C#、GO一样&#xff0c;在Node出来之前&#xff0c;JavaScript主要运行于浏览器中&#xff0c;用来控制页面的展示逻辑&#xff0c;以及交互操作等。JavaScript之所以能够在浏览器中执行&#xff0c;是…

北面羽绒服成热议产品,小红书透露出哪些营销新趋势?

小红书浓厚的种草氛围&#xff0c;为品牌创造了良好的营销环境&#xff0c;想要在小红书做好内容种草&#xff0c;需要洞察用户的真实需求来推广产品&#xff0c;实现营销效果的最大化。那如何发现小红书上的热门品类&#xff1f;制定品牌营销策略&#xff1f;挑选优质合作达人…