LeetCode题练习与总结:二叉树的后序遍历--145

一、题目描述

给你一棵二叉树的根节点 root ,返回其节点值的 后序遍历 

示例 1:

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

示例 2:

输入:root = []
输出:[]

示例 3:

输入:root = [1]
输出:[1]

提示:

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

二、方法一:递归方法

(一)解题思路

  1. 如果当前节点为空,返回。
  2. 对左子节点进行后序遍历。
  3. 对右子节点进行后序遍历。
  4. 访问当前节点,将其值加入结果列表。

(二)具体代码

import java.util.ArrayList;
import java.util.List;public class Solution {public List<Integer> postorderTraversal(TreeNode root) {List<Integer> result = new ArrayList<>();postorder(root, result);return result;}private void postorder(TreeNode node, List<Integer> result) {if (node == null) {return;}postorder(node.left, result);postorder(node.right, result);result.add(node.val);}
}

(三)时间复杂度和空间复杂度

1. 时间复杂度
  • 遍历每个节点:对于具有 N 个节点的二叉树,每个节点都会被访问一次。
  • 递归调用:每个节点都会进行两次递归调用(一次左子节点,一次右子节点)。
  • 结果添加:每个节点都会将其值添加到结果列表中,这是一个 O(1) 操作。

综上所述,时间复杂度为 O(N),其中 N 是二叉树中节点的数量。

2. 空间复杂度
  • 递归栈:递归实现需要使用栈来存储每次递归调用的信息。在最坏情况下,即树完全不平衡,每个节点都只有左子节点或只有右子节点,递归栈的深度会是 O(N)。
  • 结果列表:结果列表存储了所有节点的值,因此空间复杂度为 O(N)。

综上所述,空间复杂度为 O(N),其中 N 是二叉树中节点的数量。

注意:在实际应用中,递归调用栈的深度通常不会超过 logN,因为大多数二叉树的形状都趋于平衡。但是在分析空间复杂度时,我们通常考虑最坏情况。

(四)总结知识点

  1. 递归:这是一种编程技巧,其中一个函数直接或间接地调用自身。在这个代码中,postorder 函数递归地调用自身来遍历二叉树的左子树和右子树。

  2. 二叉树遍历:代码实现了二叉树的后序遍历。后序遍历是一种深度优先遍历策略,其中节点的遍历顺序是:左子树、右子树、根节点。

  3. 二叉树节点定义:代码中使用了TreeNode类来定义二叉树的节点,每个节点包含一个整数值val以及指向其左子节点和右子节点的指针leftright

  4. 列表(ArrayList):代码中使用ArrayList来存储后序遍历的结果。ArrayList是Java集合框架中的一个可调整大小的数组实现,用于存储对象集合。

  5. 函数参数传递:代码中的postorder函数接受两个参数,一个是TreeNode类型的节点,另一个是List<Integer>类型的结果列表。这展示了如何在函数间传递复杂类型(如自定义类和集合)的参数。

  6. 基本数据类型:代码中的int类型用于存储节点的值,这是Java的基本数据类型之一,用于表示整数。

  7. 条件语句:代码中使用了if语句来检查当前节点是否为null,这是Java中的条件语句,用于根据条件执行不同的代码路径。

  8. 函数返回值postorder函数是一个void函数,它不返回任何值,而是直接修改传入的结果列表。这展示了Java中函数可以有不同的返回类型,包括无返回值的void类型。

  9. 异常处理:虽然这个代码中没有显式的异常处理,但是在Java中,递归调用可能会引发StackOverflowError异常,如果递归深度过大,超出了栈的容量。在实际应用中,可能需要考虑异常处理来确保程序的健壮性。

三、方法二:迭代方法

(一)解题思路

  1. 使用一个栈来存储节点,一个列表来存储访问顺序。
  2. 将根节点和空节点入栈,然后进行循环。
  3. 在循环中,弹出栈顶节点,如果栈不为空且栈顶节点不等于上一个访问的节点,则将节点重新入栈,并将其右子节点和左子节点依次入栈(这样可以保证左子节点先被访问)。
  4. 如果栈为空或栈顶节点等于上一个访问的节点,则访问该节点,将其值加入结果列表。

(二)具体代码

import java.util.ArrayList;
import java.util.List;
import java.util.Stack;public class Solution {public List<Integer> postorderTraversal(TreeNode root) {List<Integer> result = new ArrayList<>();Stack<TreeNode> stack = new Stack<>();TreeNode prev = null;if (root != null) {stack.push(root);}while (!stack.isEmpty()) {TreeNode curr = stack.peek();if (prev == null || prev.left == curr || prev.right == curr) {if (curr.left != null) {stack.push(curr.left);} else if (curr.right != null) {stack.push(curr.right);} else {stack.pop();result.add(curr.val);}} else if (curr.left == prev) {if (curr.right != null) {stack.push(curr.right);} else {stack.pop();result.add(curr.val);}} else if (curr.right == prev) {stack.pop();result.add(curr.val);}prev = curr;}return result;}
}

(三)时间复杂度和空间复杂度

1. 时间复杂度
  • 每个节点处理:对于具有 N 个节点的二叉树,每个节点都会被处理一次。
  • 循环迭代:代码中使用了一个循环,循环的次数与树的节点数相同。

综上所述,时间复杂度为 O(N),其中 N 是二叉树中节点的数量。

2. 空间复杂度
  • 栈空间:迭代实现需要使用栈来存储节点。在最坏情况下,即树完全不平衡,每个节点都只有左子节点或只有右子节点,栈的深度会是 O(N)。
  • 结果列表:结果列表存储了所有节点的值,因此空间复杂度为 O(N)。

综上所述,空间复杂度为 O(N),其中 N 是二叉树中节点的数量。

注意:在实际应用中,迭代实现的空间复杂度通常不会超过 logN,因为大多数二叉树的形状都趋于平衡。但是在分析空间复杂度时,我们通常考虑最坏情况。

(四)总结知识点

  1. 迭代与栈的使用:代码使用了一个栈Stack来迭代地遍历二叉树。栈是一种后进先出(LIFO)的数据结构,用于在迭代过程中存储待处理的节点。

  2. 二叉树的后序遍历:后序遍历是一种二叉树的遍历方式,遍历顺序为:左子树、右子树、根节点。代码通过迭代的方式实现了这一遍历。

  3. 条件判断与分支:代码中使用了多个if语句来进行条件判断,根据不同的条件执行不同的代码块,以实现遍历的逻辑。

  4. 循环结构:代码使用了一个while循环来不断地从栈中取出节点进行处理,直到栈为空,即所有节点都被遍历完毕。

  5. 节点关系与指针:代码中使用了prev变量来跟踪上一个访问的节点,以便确定当前节点的左右子节点是否已经被访问过。

  6. 链表与列表:代码使用了ArrayList来存储遍历的结果,ArrayList是Java集合框架中的一个可调整大小的数组实现,用于存储对象集合。

  7. 自定义数据类型:代码中使用了TreeNode自定义类来表示二叉树的节点,每个节点包含一个整数值val以及指向其左子节点和右子节点的指针leftright

  8. 函数定义与返回值:代码定义了postorderTraversal函数,它接受一个TreeNode类型的参数(根节点),并返回一个List<Integer>类型的结果(后序遍历的节点值列表)。

  9. 基本数据类型与操作:代码中使用了int类型来存储节点的值,以及基本的赋值和比较操作。

  10. 异常处理:虽然这个代码中没有显式的异常处理,但是在Java中,使用栈时可能会遇到异常情况,例如栈溢出。在实际应用中,可能需要考虑异常处理来确保程序的健壮性。

以上就是解决这个问题的详细步骤,希望能够为各位提供启发和帮助。

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

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

相关文章

AVR晶体管测试仪开源制作与验证

AVR晶体管测试仪开源制作与验证 &#x1f4cd;原项目地址&#xff1a;https://www.mikrocontroller.net/articles/AVR_Transistortester github地址&#xff1a;https://github.com/Mikrocontroller-net/transistortester &#x1f388;EasyEDA项目地址&#xff1a;https://osh…

《数据结构与算法基础 by王卓老师》学习笔记——2.4线性表的顺序表示和实现3

1.线性表的顺序存储表示 2.顺序表示意图 定义变量的时候才会分配空间&#xff0c;光有类型是不分配空间的 3.顺序表的基本操作 增删查三种较难&#xff0c;后面会讲 4.预定义常量和类型 5.算法一&#xff1a;线性表的初始化 6.线性表的几个简单操作 7.算法二&#xff1a;顺序…

快速上手文心一言指令:解锁AI对话新纪元

快速上手文心一言指令 一、引言&#xff1a;文心一言的魅力所在二、准备工作&#xff1a;了解文心一言平台2.1 轻松注册&#xff0c;开启智能对话之旅2.2 深度探索&#xff0c;掌握界面布局奥秘2.2.1 输入框&#xff1a;智慧交流的起点2.2.2 回复区&#xff1a;即时反馈的窗口2…

IT行业入门,如何假期逆袭,实现抢跑

目录 前言 1.IT行业领域分类 2.基础课程预习指南 3.技术学习路线 4.学习资源推荐 结束语 前言 IT&#xff08;信息技术&#xff09;行业是一个非常广泛和多样化的领域&#xff0c;它包括了许多不同的专业领域和职业路径。如果要进军IT行业&#xff0c;我们应该要明确自己…

从一次 SQL 查询的全过程了解 DolphinDB 线程模型

1. 前言 DolphinDB 的线程模型较为复杂&#xff0c;写入与查询分布式表都可能需要多个类型的线程。通过了解 SQL 查询的全过程&#xff0c;可以帮助我们了解 DolphinDB 的线程模型&#xff0c;掌握 DolpinDB 的配置&#xff0c;以及优化系统性能的方法。 本教程以一个分布式 …

【鸿蒙学习笔记】基础组件 Button

官方文档&#xff1a;按钮 (Button)添加链接描述 官方文档&#xff1a;button开发指导 目录标题 属性迭代完善不含子组件的按钮包含子组件的按钮ButtonType添加事件跳转超链接提交表单悬浮按钮 属性迭代完善 不含子组件的按钮 Column({ space: 10 }) {Row() {Button(添加子目…

【原理】随机森林模型是怎么训练的

本文来自《老饼讲解-BP神经网络》https://www.bbbdata.com/ 目录 一、随机森林简介二、随机森林训练原理2.1. 随机森林的训练流程2.2. 随机森林训练的核心代码 用过随机森林的朋友都知道&#xff0c;随机森林是集成决策的一个经典代表&#xff0c;它通过训练多棵决策树&#xf…

Zigbee智能家居数据中心:微信小程序实时掌控家居传感器信息

摘要&#xff1a; 本文将介绍如何构建一个基于Zigbee和微信小程序的智能家居网关&#xff0c;实现对家居传感器数据的采集、汇总和展示。用户可通过微信小程序实时查看家中温湿度、光照等环境数据&#xff0c;为智能家居系统提供数据支撑。 关键词&#xff1a; Zigbee&#xf…

java内存管理机制(二)-内存分配

在上一篇文章中&#xff0c;我们花了较大的篇幅去介绍了JVM的运行时数据区&#xff0c;并且重点介绍了栈区的结构及作用&#xff0c;在本文中&#xff0c;我们将主要介绍对象的创建过程及在堆中的分配方式。 对象的创建 在上文我们提过一些问题&#xff0c;你的对象是怎么new…

5.3.3、二维数组案例-考试成绩统计

代码 #include <iostream> using namespace std; #include <string>int main() {//二维数组案例-考试成绩统计//1、创建二维数组int scores[3][3] {{100,100,100},{90,50,100},{60,70,80},};string names[3] { "张三","李四","王五&quo…

基于星火大模型的群聊对话分角色要素提取挑战赛|#AI夏令营#Datawhale#夏令营-Lora微调与prompt构造

赛题连接 https://challenge.xfyun.cn/topic/info?typerole-element-extraction&optionphb Datawhale Al夏令营 零基础入门大模型技术竞赛 数据集预处理 由于赛题官方限定使用了星火大模型&#xff0c;所以只能调用星火大模型的API或者使用零代码微调 首先训练数据很少…

周志华机器学习西瓜书经典来袭!PPT+课件+南瓜书

南京大学教授&#xff0c;博士生导师&#xff0c;教育部“长江学者”特聘教授&#xff0c;国家杰出青年基金获得者&#xff01;周志华老师的头衔太多了&#xff01;相信每一个从事或爱好机器学习的朋友都知道周志华老师&#xff0c;尤其是他的那本经典巨作《机器学习》&#xf…

慧哥Saas充电桩开源平台 V2.5.5

文章目录 原地址&#xff1a;https://gitee.com/chouleng/cdzkjjh&#xff0c;更换新的地址如下 [点击此链接 https://gitee.com/chouleng/huili-cloud](https://gitee.com/chouleng/huili-cloud)一、产品功能部分截图1.手机端&#xff08;小程序、安卓、ios&#xff09;2.PC端…

华为云OBS 通过S3客户端访问

华为云好像没有对S3协议的支持说明其实底层是支持S3协议的。 使用S3的时候我们会需要endpoint&#xff0c;桶名字&#xff0c;region&#xff0c;AWS_ACCESS_KEY,AWS_SECRET_KEY 其中endpoint 就是图片中的&#xff0c;桶名字也很容易找到&#xff0c;region 就是你的endpoint…

博途TIA Portal「集成自动化软件」下载安装,TIA Portal 灵活多变的编程环境

在编程领域&#xff0c;博途TIA Portal以其卓越的编程工具和灵活多变的编程环境&#xff0c;为众多用户提供了前所未有的便利。这款软件不仅支持多种编程语言&#xff0c;如梯形图&#xff08;Ladder Diagram&#xff09;、功能块图&#xff08;Function Block Diagram&#xf…

华为HCIP Datacom H12-821 卷24

1.单选题 企业大楼有大量员工通常都在上班时在大厅开始接入到公司的WLAN网络,随着每位员工走到各自的工位过程中&#xff0c;每个人的移动端叶通过漫游的方式漫游到各自的网络覆盖区域。为了尽量保证每个终端的IP地址是固定的&#xff0c;建议的做法是? A、配置VLAN Poo…

统计信号处理基础 习题解答11-13

题目 如果是一个2x1的随机矢量&#xff0c;具有PDF 证明的PDF是一个随机变量。提可以因式分解成&#xff0c;其中是一个在4.5节描述的白化变换。 解答 首先&#xff1a; 因此&#xff0c;存在&#xff1a; 也就是是Hermitian矩阵。详细的性质可以参考&#xff1a; https://z…

抠图怎么抠?教你3种一看就会的抠图工具

抠图怎么抠&#xff1f;抠图&#xff0c;作为图像处理中的一项基本而强大的技能&#xff0c;广泛应用于摄影后期、广告设计、影视特效等多个领域。它能够将图像中的特定对象或区域从背景中精确分离出来&#xff0c;便于后续编辑或与其他图像合成。随着科技的发展&#xff0c;现…

个人PayPal账户与企业PayPal账户:差异与选择

PayPal作为全球领先的在线支付平台&#xff0c;为不同用户群体设计了两种类型的账户&#xff1a;个人账户和企业账户&#xff0c;不仅为个人用户提供了便捷的支付和收款服务&#xff0c;同时也为企业用户提供了丰富的电子商务解决方案&#xff0c;让个人和企业都能使用便捷的电…

实现高效写入:Schemaless 写入性能优化指南

物联网应用常常需要收集大量的数据&#xff0c;用以支持智能控制、业务分析和设备监控等功能。然而&#xff0c;应用逻辑的更新或硬件的调整可能会导致数据采集项频繁变化&#xff0c;这是时序数据库&#xff08;Time Series Database&#xff0c;TSDB&#xff09;面临的一大挑…