首页 > 编程语言 >代码随想录算法训练营第十六天| 104.二叉树的最大深度 111.二叉树的最小深度 222.完全二叉树的节点个数

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

时间:2023-08-11 21:33:06浏览次数:33  
标签:node right int 随想录 二叉树 深度 节点

 

 104.二叉树的最大深度 (优先掌握递归)

       卡哥建议:什么是深度,什么是高度,如何求深度,如何求高度,这里有关系到二叉树的遍历方式。大家要先看视频讲解,就知道以上我说的内容了,很多录友刷过这道题,但理解的还不够。

     题目链接/文章讲解/视频讲解:https://programmercarl.com/0104.%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E6%9C%80%E5%A4%A7%E6%B7%B1%E5%BA%A6.html

      做题思路:

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

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

       而根节点的高度就是二叉树的最大深度,所以本题中我们通过后序求的根节点高度来求的二叉树最大深度。用什么遍历顺序这里多看卡哥视频理解吧。

     先求它的左子树的深度,再求右子树的深度,最后取左右深度最大的数值 再+1 (加1是因为算上当前中间节点)就是目前节点为根节点的树的深度。

      本题后序遍历的递归法代码:

 1 int getdepth(TreeNode* node) {
 2         if (node == NULL) return 0;
 3         int leftdepth = getdepth(node->left);       // 左
 4         int rightdepth = getdepth(node->right);     // 右
 5         int depth = 1 + max(leftdepth, rightdepth); // 中
 6         return depth;
 7     }
 8     int maxDepth(TreeNode* root) {
 9         return getdepth(root);
10     }

 

 111.二叉树的最小深度 (优先掌握递归)

      卡哥建议:先看视频讲解,和最大深度 看似差不多,其实 差距还挺大,有坑。

      题目链接/文章讲解/视频讲解:https://programmercarl.com/0111.%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E6%9C%80%E5%B0%8F%E6%B7%B1%E5%BA%A6.html

      做题思路:

      最小深度是从根节点到最近叶子节点的最短路径上的节点数量。

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

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

      那么使用后序遍历,其实求的是根节点到叶子节点的最小距离,就是求高度的过程,不过这个最小距离 也同样是最小深度。注意是叶子节点。什么是叶子节点,左右孩子都为空的节点才是叶子节点!如果根节点的左子树是空的话,那就从右子树开始找叶子节点。

     求二叉树的最小深度和求二叉树的最大深度的差别主要在于处理左右孩子不为空的逻辑。

       本题后序遍历的递归法代码:

 1 int getDepth(TreeNode* node) {
 2         if (node == NULL) return 0;
 3         int leftDepth = getDepth(node->left);           // 左
 4         int rightDepth = getDepth(node->right);         // 右
 5                                                         // 中
 6         // 当一个左子树为空,右不为空,这时并不是最低点
 7         if (node->left == NULL && node->right != NULL) { 
 8             return 1 + rightDepth;
 9         }   
10         // 当一个右子树为空,左不为空,这时并不是最低点
11         if (node->left != NULL && node->right == NULL) { 
12             return 1 + leftDepth;
13         }
14         int result = 1 + min(leftDepth, rightDepth);
15         return result;
16     }
17 
18     int minDepth(TreeNode* root) {
19         return getDepth(root);
20     }

 222.完全二叉树的节点个数(优先掌握递归)

      卡哥建议:需要了解,普通二叉树 怎么求,完全二叉树又怎么求

     题目链接/文章讲解/视频讲解:https://programmercarl.com/0222.%E5%AE%8C%E5%85%A8%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E8%8A%82%E7%82%B9%E4%B8%AA%E6%95%B0.html

     做题思路(我从卡哥的文章摘出来一部分):

     普通二叉树先求它的左子树的节点数量,再求右子树的节点数量,最后取总和再加一 (加1是因为算上当前中间节点)就是目前节点为根节点的节点数量。

     在完全二叉树中,底层节点一定是从左边开始连续的,只有左边的也行,只有右边的不行。若最底层为第 h 层,则该层包含 1~ 2^(h-1)  个节点。

     满二叉树的任意节点,要么度为0,要么度为2.换个说法即要么为叶子结点,要么同时具有左右孩子。

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

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

 

 

      对于情况二,如果整个树不是满二叉树,就递归其左右孩子,直到遇到满二叉树为止,用公式计算这个子树(满二叉树)的节点数量。这里关键在于如何去判断一个左子树或者右子树是不是满二叉树呢?在完全二叉树中,如果递归向左遍历的深度等于递归向右遍历的深度,那说明就是满二叉树。

     本题后序遍历的递归法代码:

 1 int countNodes(TreeNode* root) {
 2         if (root == nullptr) return 0;
 3         TreeNode* left = root->left;
 4         TreeNode* right = root->right;
 5         int leftDepth = 0, rightDepth = 0; // 这里初始为0是有目的的,为了下面求指数方便
 6         while (left) {  // 求左子树深度
 7             left = left->left;
 8             leftDepth++;
 9         }
10         while (right) { // 求右子树深度
11             right = right->right;
12             rightDepth++;
13         }
14         if (leftDepth == rightDepth) {
15             return (2 << leftDepth) - 1; // 这里记住就行,注意(2<<1) 相当于2^2,所以leftDepth初始为0,刚开始也相当于为第0层,就是根节点
16         }
17         return countNodes(root->left) + countNodes(root->right) + 1;
18     }

标签:node,right,int,随想录,二叉树,深度,节点
From: https://www.cnblogs.com/romantichuaner/p/17623850.html

相关文章

  • 代码随想录算法训练营第十五天| 层序遍历 10 ,226.翻转二叉树 101.对称二叉树 2
     层序遍历   卡哥建议:看完本篇可以一口气刷十道题,试一试, 层序遍历并不难,大家可以很快刷了十道题。  题目链接/文章讲解/视频讲解:https://programmercarl.com/0102.%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E5%B1%82%E5%BA%8F%E9%81%8D%E5%8E%86.html  做题思......
  • 二叉树的堂兄弟节点
    在二叉树中,根节点位于深度0处,每个深度为k的节点的子节点位于深度k+1处。如果二叉树的两个节点深度相同,但父节点不同,则它们是一对堂兄弟节点。我们给出了具有唯一值的二叉树的根节点root,以及树中两个不同节点的值x和y。只有与值x和y对应的节点是堂兄弟节点时,......
  • 解锁Python集合的妙用:常用函数与实例深度解析
    Python的集合(Set)是一种无序且不重复的数据结构,拥有强大的去重和集合运算功能。在这篇博客中,我们将深入探讨集合的常用函数,并通过实际案例为你展示其灵活应用。创建集合集合可以通过花括号来创建,也可以使用内置函数set()来转换其他可迭代对象为集合。#创建集合my_set={1,2,3}......
  • Kafka深度解析
    背景介绍Kafka简介Kafka是一种分布式的,基于发布/订阅的消息系统。主要设计目标如下:以时间复杂度为O(1)的方式提供消息持久化能力,即使对TB级以上数据也能保证常数时间的访问性能高吞吐率。即使在非常廉价的商用机器上也能做到单机支持每秒100K条消息的传输支持KafkaServer间的......
  • 使用LabVIEW 实现物体识别、图像分割、文字识别、人脸识别等深度视觉
    前言哈喽,各位朋友们,这里是virobotics(仪酷智能),这两天有朋友私信问之前给大家介绍的工具包都可以实现什么功能,最新的一些模型能否使用工具包加载,今天就给大家介绍一下博主目前使用工具包已经实现的深度视觉模型及案例下表为前期写过的一些范例介绍,朋友们可以按需点击查看名字......
  • JTA 深度历险 - 原理与实现
    http://www.ibm.com/developerworks/cn/java/j-lo-jta/在J2EE应用中,事务是一个不可或缺的组件模型,它保证了用户操作的ACID(即原子、一致、隔离、持久)属性。对于只操作单一数据源的应用,可以通过本地资源接口实现事务管理;对于跨数据源(例如多个数据库,或者数据库与JMS)的大型应用,则......
  • 二叉树和B树
    1、树(Tree)的基本概念 节点、根节点、父节点、子节点、兄弟节点一棵树可以没有任何节点,称为空树一棵树可以只有1个节点,也就是只有根节点子树、左子树、右子树节点的度(degree):子树的个数树的度:所有节点度中的最大值叶子节点(leaf):度为0的节点非叶子节点:度不为0的节点......
  • 【CV实战】年轻人的第一个深度学习图像分割项目应该是什么样的(Pytorch框架)?...
    我们上次给新手们介绍了第一个合适入门的深度学习CV项目,可阅读【CV实战】年轻人的第一个深度学习CV项目应该是什么样的?(支持13大深度学习开源框架),本次我们再给大家介绍一个新的任务,图像分割,包括数据的处理,模型的训练与测试。作者&编辑|言有三本文资源与图像分割结果展示1项目背......
  • MATLAB用深度学习长短期记忆 (LSTM) 神经网络对智能手机传感器时间序列数据进行分类|
    原文链接:http://tecdat.cn/?p=26318原文出处:拓端数据部落公众号 最近我们被客户要求撰写关于长短期记忆(LSTM)神经网络的研究报告,包括一些图形和统计输出。此示例说明如何使用长短期记忆(LSTM)网络对序列数据的每个时间步长进行分类。要训​​练深度神经网络对序列数据......
  • 代码随想录算法训练营第一天| 704. 二分查找、27. 移除元素
    704二分查找题目给定一个n个元素有序的(升序)整型数组nums和一个目标值target,写一个函数搜索nums中的target,如果目标值存在返回下标,否则返回-1。第一想法判断条件是value=target因为数组是升序,其实每种查找方法应该相差不大?不过题目都标了二分查找了emmm思......