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

代码随想录算法训练营第十六天

  • LeetCode 104.二叉树的最大深度
    • 题目描述
    • 思路
    • 递归后序遍历参考代码
    • 递归前序遍历参考代码
    • 总结
  • LeetCode 111.二叉树的最小深度
    • 题目描述
    • 思路
    • 参考代码
  • LeetCode 222.完全二叉树的节点个数
    • 题目描述
    • 思路
    • 后序遍历参考代码1
    • 后序遍历参考代码2

LeetCode 104.二叉树的最大深度

题目链接:104.二叉树的最大深度
文章讲解:代码随想录#104.二叉树的最大深度
视频讲解:104.二叉树的最大深度

题目描述

给定一个二叉树 root ,返回其最大深度
二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。

示例1
在这里插入图片描述

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

示例2

输入:root = [1,null,2]
输出:2

提示

  • 树中节点的数量在 [0, 104] 区间内。
  • -100 <= Node.val <= 100

思路

什么是二叉树节点的高度?么是二叉树节点的深度?

  • 二叉树节点的深度:指从根节点到该节点的最长简单路径边的条数或者节点数(取决于深度从0开始还是从1开始)
  • 二叉树节点的高度:指从该节点到叶子节点的最长简单路径边的条数或者节点数(取决于高度从0开始还是从1开始)
    使用前序求的就是深度,使用后序求的是高度
    根节点的高度就是二叉树的最大深度,所以可以通过后序遍历来求二叉树的最大深度。

递归后序遍历参考代码

#define MAX(a, b) (a) > (b) ? (a) : (b)
// 使用后序遍历计算二叉树的高度,二叉树的最大深度也就是根节点到叶子节点的高度
int treeDepth(struct TreeNode *node)
{if (node == NULL) {return 0;}int lDepth = treeDepth(node->left); // 左int rDepth = treeDepth(node->right); // 右int depth = MAX(lDepth, rDepth); // 中return depth + 1;}
int maxDepth(struct TreeNode* root) {return treeDepth(root);
}

递归前序遍历参考代码

int res;// 使用前序遍历计算二叉树的最大深度,必须需要一个变量来记录当前遍历的depth
void treeDepth(struct TreeNode *node, int depth)
{res = res > depth ? res : depth;  // 中if (node->left == NULL && node->right == NULL) {return ;}if (node->left != NULL) { // 左depth++;treeDepth(node->left, depth);depth--; // 回溯}if (node->right != NULL) { // 右depth++;treeDepth(node->right, depth);depth--; // 回溯}return;
}int maxDepth(struct TreeNode* root) {res = 0;if (root == NULL) {return res;}treeDepth(root, 1);return res;
}

总结

  1. 递归相对简单一些,后面有时间了深度用层序遍历解决这道题

LeetCode 111.二叉树的最小深度

题目链接:111.二叉树的最小深度
文章讲解:代码随想录#111.二叉树的最小深度
视频讲解: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

思路

这道题关键点是要计算从根节点到最近叶子节点的最短路径上的节点数量。
需要注意的是如果左子树为空,右子树不为空,则最小深度为1+右子树的深度。同样,如果右子树为空,左子树不为空,则最小深度为1+左子树的深度。

参考代码

int minDepth(struct TreeNode* root) {if (root == NULL) {return 0;}int lDepth = minDepth(root->left); // 左int rDepth = minDepth(root->right); // 右if (root->left == NULL && root->right != NULL) { // 处理中节点return 1 + rDepth;}if (root->left != NULL && root->right == NULL) {return 1 + lDepth;}int depth = lDepth > rDepth ? rDepth : lDepth; // 中return 1 + depth;
}

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

题目链接:222.完全二叉树的节点个数
文章讲解:代码随想录#222.完全二叉树的节点个数
视频讲解:要理解普通二叉树和完全二叉树的区别! | LeetCode:222.完全二叉树节点的数量

题目描述

给你一棵 完全二叉树 的根节点 root ,求出该树的节点个数。

完全二叉树 的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1~ 2h 个节点。

示例1
在这里插入图片描述

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

示例2

输入:root = []
输出:0

示例 3

root = [1]
1

提示

  • 树中节点的数目范围是[0, 5 * 10^4]
  • 0 <= Node.val <= 5 * 10^4
  • 题目数据保证输入的树是 完全二叉树

思路

第一反应就是深度遍历或层序遍历所有的节点,时间复杂度为O(n)。
但这不是最优解,理解完全二叉树的特点后,会有更好的解决方案。
在完全二叉树中,除了最底层节点可能没有填充满以外,其余层的是一个满二叉树,而且最底层的节点都集中在最左边。
如果最底层为n层,则该层包含的节点数为[1, 2^(n-1)],除最底层以外的节点数为2^(n-1)-1。
对于一个完全二叉树,分别递归左孩子和右孩子,递归到某一深度一定会有左孩子或右孩子是满二叉树,如果是满二叉树可以根据深度k计算节点数为2^k-1。

具体思路可以参考代码随想录。

后序遍历参考代码1

int countNodes(struct TreeNode* root) {if (root == NULL) {return 0;}int lcnt = countNodes(root->left);int rcnt = countNodes(root->right);return 1 + lcnt + rcnt;    
}

后序遍历参考代码2

// 根据完全二叉树特性
int countNodes(struct TreeNode* root) {if (root == NULL) {return 0;}int lcnt = 0, rcnt = 0;struct TreeNode* lnode = root->left;struct TreeNode* rnode = root->right;while (lnode) {lnode = lnode->left;lcnt++;}while (rnode) {rnode = rnode->right;rcnt++;}if (lcnt == rcnt) {return (2 << lcnt) - 1;}return 1 +  countNodes(root->left) + countNodes(root->right);
}

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

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

相关文章

Stable Diffusion ComfyUI安装详细教程

上一篇文章介绍了sd-webui的安装教程&#xff0c;但学习一下ComfyUI这种节点流程式的对理解AI绘画有较大帮助&#xff0c;而且后期排查错误会更加方便&#xff0c;熟练后用这种方式做AI绘画可玩性会更多。 文章目录 一、安装包说明二、安装文件介绍三、安装步骤四、汉化五、云主…

Linux-ls命令

目录 ls&#xff1a;查看目录下文件/文件夹 ls -l&#xff1a;列表显示文件 ls -a&#xff1a;显示所有文件正常情况下‘ . ’开头的文件是隐藏的 ls -la&#xff1a;以列表形式显示所有文件包括隐藏文件 ls -lt&#xff1a;按时间倒序查看文件 ls -R&#xff1a;递归方式…

Open CASCADE学习|曲线向曲面投影

在三维空间中&#xff0c;将曲线向曲面投影通常涉及复杂的几何计算。这个过程可以通过多种方法实现&#xff0c;但最常见的是使用数学和几何库&#xff0c;如OpenCASCADE&#xff0c;来处理这些计算。 在OpenCASCADE中&#xff0c;投影曲线到曲面通常涉及以下步骤&#xff1a;…

第14讲投票帖子详情实现

投票帖子详情实现 后端,根据id查询投票帖子信息&#xff1a; /*** 根据id查询* param id* return*/ GetMapping("/{id}") public R findById(PathVariable(value "id")Integer id){Vote vote voteService.getById(id);WxUserInfo wxUserInfo wxUserInf…

简单介绍数据结构的基本概念

数据结构的基本概念 常用术语 数据 数据&#xff08;Data&#xff09;是客观事物的符号表示&#xff0c;是所有能输入到计算机中并被计算机程序处理的符号的总称。例如&#xff1a;整数、字符串、图形、图像、声音和动画等 数据元素 数据元素&#xff08;Data Element&…

Shiro反弹shell和权限绕过含工具包

★★免责声明★★ 文章中涉及的程序(方法)可能带有攻击性&#xff0c;仅供安全研究与学习之用&#xff0c;读者将信息做其他用途&#xff0c;由Ta承担全部法律及连带责任&#xff0c;文章作者不承担任何法律及连带责任。 1、前言 反序列化漏洞原理和Shiro反序列化漏洞原理请参…

安装 Windows 7

1.镜像安装 镜像安装:安装Windows 7 2.安装过程(直接以图的形式呈现) 等待安装成功即可

Linux——网络通信TCP通信常用的接口和tcp服务demo

文章目录 TCP通信所需要的套接字socket()bind()listen()acceptconnect() 封装TCP socket TCP通信所需要的套接字 socket() socket()函数主要作用是返回一个描述符&#xff0c;他的作用就是打开一个网络通讯端口&#xff0c;返回的这个描述符其实就可以理解为一个文件描述符&a…

防御-day5-防火墙综合实验

一、实验拓扑 二、实验要求 1、办公区设备可以通过电信链路和移动链路上网(多对多的NAT、并且需要保留一个公网IP不能用来转换)。 2、分公司的设备可以通过总公司的移动链路和电信链路访问到DMZ区的http服务器 3、分公司内部的客户端可以通过公网地址访问到内部的服务器。 三、…

0206-1-网络层

第 4 章 网络层 网络层提供的两种服务 虚电路服务 数据报服务 概要: 虚电路服务与数据报服务的对比 网际协议 IP 网际协议 IP 是 TCP/IP 体系中两个最主要的协议之一。与 IP 协议配套使用的还有四个协议&#xff1a; 地址解析协议 ARP (Address Resolution Protocol)逆地…

数据结构——lesson3单链表介绍及实现

目录 1.什么是链表&#xff1f; 2.链表的分类 &#xff08;1&#xff09;无头单向非循环链表&#xff1a; &#xff08;2&#xff09;带头双向循环链表&#xff1a; 3.单链表的实现 &#xff08;1&#xff09;单链表的定义 &#xff08;2&#xff09;动态创建节点 &#…

林浩然与杨凌芸的Java List大冒险

林浩然与杨凌芸的Java List大冒险 Lin Haoran and Yang Lingyun’s Java List Adventure 在一个阳光明媚的日子&#xff0c;程序员界的“侠客”林浩然和他那聪明伶俐的同事兼好友杨凌芸正在Java王国里进行一场别开生面的大冒险。这次他们的目标是征服两个强大的List家族成员——…