代码随想录-Day16

104. 二叉树的最大深度

方法一:深度优先搜索

class Solution {public int maxDepth(TreeNode root) {if (root == null) {return 0;} else {int leftHeight = maxDepth(root.left);int rightHeight = maxDepth(root.right);return Math.max(leftHeight, rightHeight) + 1;}}
}

这段代码定义了一个名为 Solution 的类,其中包含一个方法 maxDepth 用于计算二叉树的最大深度。最大深度是从根节点到最远叶子节点的最长路径上的边数。方法使用了递归的策略来实现这一计算。以下是代码的详细解析:

  • 方法签名:
    public int maxDepth(TreeNode root)
    
  • 输入参数:
    TreeNode root - 二叉树的根节点。
  • 输出:
    返回类型为 int 的最大深度值。

代码逻辑:

  1. 基本情况处理:

    • 首先检查根节点 root 是否为空 (if (root == null) )。如果树为空,则没有节点,深度为0,所以直接返回0。
  2. 递归计算左右子树深度:

    • 如果根节点不为空,递归地计算左子树的最大深度 (int leftHeight = maxDepth(root.left);) 和右子树的最大深度 (int rightHeight = maxDepth(root.right);)。
  3. 确定整棵树的最大深度:

    • 使用 Math.max(leftHeight, rightHeight) 来获取左、右子树中较大的深度值,然后加1(因为要包括根节点的高度),得到整棵树的最大深度。
    • 最后,返回这个计算出的最大深度值。

通过递归调用,该方法能够遍历到二叉树的每一个节点,并通过比较左右子树的深度来确定整棵树的最大深度,是一种分治策略的典型应用。

方法二:广度优先搜索

class Solution {public int maxDepth(TreeNode root) {if (root == null) {return 0;}Queue<TreeNode> queue = new LinkedList<TreeNode>();queue.offer(root);int ans = 0;while (!queue.isEmpty()) {int size = queue.size();while (size > 0) {TreeNode node = queue.poll();if (node.left != null) {queue.offer(node.left);}if (node.right != null) {queue.offer(node.right);}size--;}ans++;}return ans;}
}

这段代码定义了一个名为 Solution 的类,其中包含一个方法 maxDepth 用于计算二叉树的最大深度,即树中最长路径的边数。这里使用了广度优先搜索(BFS)策略来实现,具体解析如下:

  • 方法签名:
    public int maxDepth(TreeNode root)
    
  • 输入参数:
    TreeNode root - 二叉树的根节点。
  • 输出:
    返回类型为 int 的最大深度值。

代码逻辑:

  1. 基本情况处理:

    • 首先检查根节点 root 是否为空 (if (root == null) )。如果是,表明树为空,深度为0,直接返回0。
  2. 初始化队列与广度优先遍历:

    • 创建一个队列 queue,并将根节点 root 入队列 (queue.offer(root);),用于开始广度优先遍历。
    • 定义一个变量 ans 用于存储当前已遍历的层数,初始化为0。
    • 当队列非空时,进行循环,意味着还有节点未遍历:
      • 获取当前层的节点数 size,即队列的大小。
      • 通过内层循环遍历当前层的所有节点:
        • 弹出队首节点 node,处理该节点(实际上这里直接弹出,没有具体操作,重点在于处理其子节点)。
        • 若该节点的左子节点不为空,则左子节点入队列。
        • 若该节点的右子节点不为空,则右子节点入队列。
        • size 减1,表示当前层的一个节点已被处理完毕。
      • 当一层处理完后,ans 增加1,表示已遍历完一层。
  3. 返回结果:

    • 当所有节点遍历完毕,队列为空时,返回 ans 作为最大深度。

此算法通过BFS遍历二叉树,每遍历完一层深度加1,最终得到的 ans 即为树的最大深度,这种方式适用于任何形态的二叉树结构,包括不平衡树。

111. 二叉树的最小深度

方法一:深度优先搜索

class Solution {public int minDepth(TreeNode root) {if (root == null) {return 0;}if (root.left == null && root.right == null) {return 1;}int min_depth = Integer.MAX_VALUE;if (root.left != null) {min_depth = Math.min(minDepth(root.left), min_depth);}if (root.right != null) {min_depth = Math.min(minDepth(root.right), min_depth);}return min_depth + 1;}
}

这段代码是 Java 语言实现的一个解决方案,用于计算二叉树的最小深度。给定一个二叉树,最小深度是从根节点到最近叶子节点的最短路径上的边数。这里使用了递归的方法来解决这个问题。下面是对代码的详细解释:

  • public int minDepth(TreeNode root) 定义了一个公开方法,接受一个 TreeNode 类型的参数 root,表示二叉树的根节点,返回值为最小深度。

  • 首先检查 root == null,如果根节点为空,则说明这是一个空树,其深度为 0,所以返回 0。

  • 然后检查 root.left == null && root.right == null,如果当前节点既没有左子节点也没有右子节点,说明当前节点就是叶子节点,此时深度为 1,所以返回 1。

  • 接下来定义一个变量 min_depth 初始化为 Integer.MAX_VALUE,用于保存左右子树中的最小深度。

  • 通过条件语句 if (root.left != null) 检查左子节点是否存在,如果存在,则递归调用 minDepth(root.left) 获取左子树的最小深度,并更新 min_depth 的值。

  • 同样,通过条件语句 if (root.right != null) 检查右子节点是否存在,如果存在,则递归调用 minDepth(root.right) 获取右子树的最小深度,并更新 min_depth 的值。

  • 最后,返回 min_depth + 1 作为整棵树的最小深度。这里的 “+1” 是因为需要加上从父节点到当前节点的这一边。

整个函数通过递归遍历整棵二叉树,逐步计算并比较左右子树的最小深度,从而找到从根节点到最近叶子节点的最短路径长度。

方法二:广度优先搜索

class Solution {class QueueNode {TreeNode node;int depth;public QueueNode(TreeNode node, int depth) {this.node = node;this.depth = depth;}}public int minDepth(TreeNode root) {if (root == null) {return 0;}Queue<QueueNode> queue = new LinkedList<QueueNode>();queue.offer(new QueueNode(root, 1));while (!queue.isEmpty()) {QueueNode nodeDepth = queue.poll();TreeNode node = nodeDepth.node;int depth = nodeDepth.depth;if (node.left == null && node.right == null) {return depth;}if (node.left != null) {queue.offer(new QueueNode(node.left, depth + 1));}if (node.right != null) {queue.offer(new QueueNode(node.right, depth + 1));}}return 0;}
}

这段代码同样实现了计算二叉树最小深度的功能,但采用的是广度优先搜索(BFS)的方法,而非之前的深度优先搜索(DFS)。下面是代码的解释:

  • 首先定义了一个内部类 QueueNode,它包含两个成员变量:一个 TreeNode node 用于存储树的节点,一个 int depth 用于记录该节点到根节点的距离(深度)。

  • public int minDepth(TreeNode root) 方法接收一个 TreeNode 类型的参数 root,表示二叉树的根节点,返回值为最小深度。

  • 如果根节点为空,返回 0,表示空树。

  • 创建一个队列 Queue<QueueNode> queue 来进行广度优先搜索,并初始化一个 QueueNode 对象,包含根节点及其深度 1,然后将此对象加入队列。

  • 使用 while 循环处理队列直到其为空。在每次循环中:

    • 弹出队列头部的 QueueNode,获取其中的节点 node 和当前深度 depth
    • 如果当前节点 node 无左右子节点,即为叶子节点,直接返回当前深度 depth 作为最小深度。
    • 若当前节点有左子节点,创建一个新的 QueueNode 对象,包含左子节点和当前深度加 1,然后将其加入队列。
    • 若当前节点有右子节点,创建一个新的 QueueNode 对象,包含右子节点和当前深度加 1,同样将其加入队列。
  • 当队列变空时,理论上不应该发生,因为只要有叶子节点就应该提前返回结果。但为了保持函数返回类型一致性,这里返回 0。在实际应用中,这个返回 0 的情况应该永远不会被执行到,因为一旦发现叶子节点就会立即返回其深度。

通过广度优先搜索,这个算法能够遍历每一层的节点,当遇到第一个没有子节点(即叶子节点)的节点时,就可以确定这是到根节点的最短路径,从而得到最小深度。

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

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

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

class Solution {public int countNodes(TreeNode root) {if (root == null) {return 0;}int level = 0;TreeNode node = root;while (node.left != null) {level++;node = node.left;}int low = 1 << level, high = (1 << (level + 1)) - 1;while (low < high) {int mid = (high - low + 1) / 2 + low;if (exists(root, level, mid)) {low = mid;} else {high = mid - 1;}}return low;}public boolean exists(TreeNode root, int level, int k) {int bits = 1 << (level - 1);TreeNode node = root;while (node != null && bits > 0) {if ((bits & k) == 0) {node = node.left;} else {node = node.right;}bits >>= 1;}return node != null;}
}

这段代码是用来解决一个二叉树问题的,具体问题是计算完全二叉树中的节点个数。完全二叉树是每一层(除了可能的最后一层外)都完全填充的树,并且所有结点都尽可能地集中在左侧。代码采用了两种方法结合的策略:首先通过高度来定位最后一个非空节点所在的层数,然后在一个可能的范围内利用二分查找确定实际的节点数量。下面是详细的解释:

  • public int countNodes(TreeNode root) 方法是主要的接口,接收一个 TreeNode 类型的参数 root,表示二叉树的根节点,返回值为树中的节点总数。

  • 首先,如果根节点为空,直接返回 0,因为空树没有节点。

  • 接着,通过一个循环计算树的高度(层数),同时找到最后一层的第一个节点。level 初始化为 0,node 初始化为 root,循环条件是 node.left != null,意味着只要当前节点有左子节点,就继续向左下移动并增加层数。

  • 计算出 level 后,可以推断出这棵完全二叉树节点数量的大致范围:至少有 low = 1 << level 节点(即2的level次方),最多有 high = (1 << (level + 1)) - 1 节点。这里利用位运算快速计算2的幂次。

  • 然后,在 lowhigh 之间使用二分查找确定实际的节点数量。在循环中,首先计算中间值 mid,然后调用 exists() 函数检查在这个位置上是否存在节点。根据 exists() 的返回值调整查找范围:如果节点存在,则说明实际节点数至少为 mid,因此更新 low = mid;否则,节点不存在,说明实际节点数小于 mid,则更新 high = mid - 1

  • low >= high 时,二分查找结束,返回 low 作为完全二叉树的确切节点数。

  • public boolean exists(TreeNode root, int level, int k) 是一个辅助函数,用来判断在给定层级 (level) 和位置 (k) 是否存在节点。它模拟从根节点开始,根据二进制位确定向左还是向右走,逐步向下查找。bits 变量用于控制每一步的移动方向,初始值为 1 << (level - 1),表示在当前层级上最左边的节点所对应的二进制位。随着循环的进行,bits 右移一位,直到为0,表示已经到达目标层级并完成查找。如果最终 node 不为空,说明对应位置的节点存在,返回 true;否则,返回 false

这种解法巧妙地结合了树的高度信息与二分查找的效率,可以在对数时间内解决问题,对于大规模的完全二叉树特别有效。

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

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

相关文章

深入解读HTTP状态码:分类、含义、应用场景与故障排查指南

HTTP状态码作为超文本传输协议(HTTP)响应的重要组成部分,为客户端与服务器之间的交互提供了清晰的状态反馈。本文将全面展开对HTTP状态码的深入解读,涵盖其分类、具体含义、典型应用场景以及在故障排查中的实用价值,旨在帮助开发者与运维人员更好地理解和应对各类HTTP响应…

Postman使用技巧

Postman是一款广泛使用的API开发和测试工具&#xff0c;专为简化Web服务API的开发、测试、文档编制和协作过程而设计。它支持各种HTTP请求方法&#xff0c;包括GET、POST、PUT、DELETE等&#xff0c;允许用户轻松地构建和发送请求&#xff0c;以及检查响应。 本文介绍几个提升效…

vscode 的 AI 协助插件 Tabnine / Codeium

4.1、Tabnine 描述&#xff1a;Tabnine 是一款基于深度学习技术的代码自动补全工具。该插件支持多种编程语言&#xff0c;包括 Python、JavaScript、TypeScript、Java 和 Go 等。它可以根据您输入的代码段和上下文信息&#xff0c;预测并推荐可能的代码补全选项&#xff0c;从而…

GitHub的原理及应用详解(三)

本系列文章简介&#xff1a; GitHub是一个基于Git版本控制系统的代码托管平台&#xff0c;为开发者提供了一个方便的协作和版本管理的工具。它广泛应用于软件开发项目中&#xff0c;包括但不限于代码托管、协作开发、版本控制、错误追踪、持续集成等方面。 GitHub的原理可以简单…

每周一算法:Prim算法求最小生成树

题目链接 [最短网络] 题目描述 Farmer John 被选为他们镇的镇长&#xff01;他其中一个竞选承诺就是在镇上建立起互联网&#xff0c;并连接到所有的农场。当然&#xff0c;他需要你的帮助。 FJ 已经给他的农场安排了一条高速的网络线路&#xff0c;他想把这条线路共享给其他…

第4章 网络层

4.1网络层的功能 1.异网互联:使用路由器连接数据链路层和物理层均不同的网络。【路由器连接的设备物理层&#xff0c;数据链路层和网络层可以不同】 2.转发:从一个端口输入保存后选择另一个端口转发【微观】 3.路由选择:选择合适的路由线路【宏观】 4.SDN的基本概念: 数据平…

【shell】脚本案例2

shell案例&#xff1a; 选择mysql版本 在上面的示例中&#xff0c;没有办法在选择了水果后退出&#xff0c;它会一直让我们选择。如果我们希望选择后就退出&#xff0c;则需要在脚本添加 break 打印九九乘法表 打印三角形&#xff08;10行10列&#xff09; 循环输出0~10之…

目前流行的前端框架有哪些?

目前流行的前端框架有很多&#xff0c;它们可以帮助开发者快速构建高质量的前端应用程序。本文将介绍一些目前比较受欢迎的前端框架&#xff0c;并分析它们的优缺点。 React React 是一个由 Facebook 开发的开源前端JavaScript库&#xff0c;用于构建用户界面&#xff0c;尤其…

Ollama本地运行 Mistral-7B-Instruct-v0.3

Ollama本地运行 Mistral-7B-Instruct-v0.3 0. 引言1. 运行 mistral:7b-instruct-v0.3-q8_02. 简单问个问题 0. 引言 Mixtral 5月23日发布了 Mistral-7B-Instruct-v0.3&#xff0c;支持 function calling&#xff0c;今天简单运行一下。 1. 运行 mistral:7b-instruct-v0.3-q8_…

头歌03-最长公共子序列

给定两个无序的序列 X{x_1,x_2,⋯,x_m } 和 Y{Y_1,Y_2,⋯,Y_n } ,求 X 和 Y 长度最长的公共子序列。 序列的子序列是指&#xff1a;从给定序列中随意地&#xff08;不一定连续&#xff09;去掉若干个字符&#xff08;可能一个也不去掉&#xff09;后所形成的字符序列。如果序列…

【AI如何帮你编写测试用例并输出表格格式】

1、工具&#xff1a;顺便使用一款生成式AI即可&#xff0c;此处用的是ChatGPT&#xff0c;Kimi这两个工具试验。 2、首先要拿到需求文档&#xff0c;根据需求文档向AI发出如下指令&#xff08;Prompt&#xff09; “请根据下面这段需求&#xff0c;编写测试用例&#xff1a; …

在CentOS上手动配置静态IP地址及多网卡路由策略

在管理服务器时&#xff0c;手动配置静态IP地址是一项基本而关键的任务&#xff0c;尤其是在涉及多网卡的复杂网络环境中。静态IP配置确保了服务器的稳定访问&#xff0c;有助于避免由于IP地址动态变化引起的潜在问题。本文将探讨如何在CentOS系统中手动设置静态IP地址&#xf…

python从0开始学习(十二)

目录 前言 1、字符串的常用操作 2、字符串的格式化 2.1 格式化字符串的详细格式&#xff08;针对format形式&#xff09; ​编辑 总结 前言 上一篇文章我们讲解了两道关于组合数据类型的题目&#xff0c;本篇文章我们将学习新的章节&#xff0c;学习字符串及正则表达式。 …

字节跳动(校招)算法原题

大模型"价格战"越演越烈 昨天的 文章 提到&#xff0c;自从 5 月 15 号&#xff0c;字节跳动发布了击穿行业底价的豆包大模型后&#xff0c;各大厂家纷纷跟进降价&#xff0c;而且都不是普通降价&#xff0c;要么降价 90% 以上&#xff0c;要么直接免费。 今天是豆包…

【Linux】centos7下载安装Python3.10,下载安装openssl1.1.1

目录 centos7下载安装Python&#xff08;版本3.10.14&#xff09; &#xff08;1&#xff09;网页下载python压缩包&#xff0c;并解压缩 &#xff08;2&#xff09;编译安装 Python在make altinstall时&#xff0c;报错及解决 &#xff08;3&#xff09;将安装目录和可执…

2024电工杯数学建模A题思路+模型+代码

2024电工杯数学建模A题思路模型代码&#xff0c;开赛后第一时间更新&#xff0c;更新见文末名片 以下为2023年电工杯A提思路&#xff1a; A题: 电采暖负荷参与电力系统功率调节的技术经济分析。 典型住户电采暖负荷用电行为分析&#xff1a; a) 分析典型房间温变过程微分方程…

EM算法求解高斯混合模型参数公式推导

高斯混合模型介绍 高斯混合模型&#xff08;Gaussian Mixture Model&#xff0c;简称GMM&#xff09;是一种经典的概率模型&#xff0c;被广泛应用于数据挖掘、模式识别和机器学习等领域。它采用多个高斯分布组合来对数据进行建模&#xff0c;每个高斯分布对应于数据中的一个子…

ROCm上运行情感分析:使用卷积神经网络

15.3. 情感分析&#xff1a;使用卷积神经网络 — 动手学深度学习 2.0.0 documentation (d2l.ai) 代码 import torch from torch import nn from d2l import torch as d2lbatch_size 64 train_iter, test_iter, vocab d2l.load_data_imdb(batch_size)def corr1d(X, K):w K.s…

分布式任务调度内的 MySQL 分页查询优化

作者&#xff1a;vivo 互联网数据库团队- Qiu Xinbo 本文主要通过图示介绍了用主键进行分片查询的过程&#xff0c;介绍了主键分页查询存在SQL性能问题&#xff0c;如何去创建高效的索引去优化主键分页查询的SQL性能问题。 对于数据分布不均如何发现&#xff0c;提供了一些SQL…

C语言初阶——5操作符

一、算数操作符 除了% 操作符之外&#xff0c;其他的几个操作符可以作用于整数和浮点数。对于/ 操作符如果两个操作数都为整数&#xff0c;执行整数除法。而只要有浮点数执行的就是浮点数除 法。% 操作符的两个操作数必须为整数。返回的是整除之后的余数。 1、类型转换 C语言…