当前位置: 首页 > news >正文

《代码随想录》--二叉树(一)

《代码随想录》--二叉树 第一部分

  • 1、二叉树的递归遍历
  • 2、二叉树的迭代遍历
  • 3、统一风格的迭代遍历代码
  • 4、二叉树的层序遍历
  • 226.翻转二叉树

1、二叉树的递归遍历

前序遍历

中序遍历

后序遍历

代码

  • 前序遍历
class Solution {public List<Integer> preorderTraversal(TreeNode root) {List<Integer> list = new ArrayList<>();preOrder(root,list);return list;}public void preOrder(TreeNode root,List<Integer> list){if(root == null) return;list.add(root.val);preOrder(root.left,list);preOrder(root.right,list);}
}
  • 中序遍历
class Solution {public List<Integer> inorderTraversal(TreeNode root) {List<Integer> list = new ArrayList<>();inOrder(root,list);return list;}public void inOrder(TreeNode root,List<Integer> list){if(root == null) return;inOrder(root.left,list);list.add(root.val);inOrder(root.right,list);}
}
  • 后序遍历
class Solution {public List<Integer> postorderTraversal(TreeNode root) {List<Integer> list = new ArrayList<>();postOrder(root,list);return list;}public void postOrder(TreeNode root,List<Integer> list){if(root == null) return;postOrder(root.left,list);postOrder(root.right,list);list.add(root.val);}
}

2、二叉树的迭代遍历

前序遍历

中序遍历

后序遍历

代码

  • 前序遍历
class Solution {public List<Integer> preorderTraversal(TreeNode root) {List<Integer> result = new ArrayList<>();if(root == null) return result;Stack<TreeNode> stack = new Stack<>();stack.push(root);while(!stack.isEmpty()){TreeNode node = stack.pop();result.add(node.val);if(node.right != null) stack.push(node.right);if(node.left != null) stack.push(node.left);}return result;}
}
  • 中序遍历
class Solution {public List<Integer> inorderTraversal(TreeNode root) {List<Integer> list = new ArrayList<>();Stack<TreeNode> stack = new Stack<>();TreeNode cur = root;while(cur != null || !stack.isEmpty()){if(cur != null){stack.push(cur);cur = cur.left;}else{TreeNode node = stack.pop();list.add(node.val);cur = node.right;}}return list;}
}
  • 后序遍历
class Solution {public List<Integer> postorderTraversal(TreeNode root) {List<Integer> list = new ArrayList<>();if(root == null) return list;Stack<TreeNode> stack = new Stack<>();stack.push(root);while(!stack.isEmpty()){TreeNode node = stack.pop();list.add(node.val);if(node.left != null) stack.push(node.left);if(node.right != null) stack.push(node.right);}Collections.reverse(list);return list;}
}

分析

  • 非递归的遍历都需要借助来编写代码
  • 前序遍历:
    • 前序遍历是中左右的顺序
    • 先把中间节点放入栈中
    • 再放入右孩子(为什么?因为栈先入后出)
    • 再放入左孩子
  • 中序遍历:
    • 中序遍历的顺序是左中右,但是我们的处理顺序和访问顺序不一致,所以借助指针
    • 定义一个cur指针帮助我们遍历,栈用来处理节点上的元素
  • 后序遍历:
    • 后序遍历的顺序是左右中,可以根据前序遍历改变得到
    • 将遍历顺序改为中左右,最后得到的结果是中右左
    • 反转数组得到正确结果

3、统一风格的迭代遍历代码

  • 前面的迭代遍历代码风格不统一,不像递归代码一样修改代码的位置就能写出三种遍历方式
  • 这里借助空节点标记法

代码

  • 前序
class Solution {public List<Integer> preorderTraversal(TreeNode root) {List<Integer> list = new ArrayList<>();Stack<TreeNode> stack = new Stack<>();if(root != null) stack.push(root);while(!stack.isEmpty()){TreeNode node = stack.peek();if(node != null){node = stack.pop();if(node.right != null) stack.push(node.right);if(node.left != null) stack.push(node.left);stack.push(node);stack.push(null);}else{stack.pop();node = stack.pop();list.add(node.val);}}return list;}
}
  • 中序
class Solution {public List<Integer> inorderTraversal(TreeNode root) {List<Integer> list = new ArrayList<>();Stack<TreeNode> stack = new Stack<>();if(root != null) stack.push(root);while(!stack.isEmpty()){TreeNode node = stack.peek();if(node != null){node = stack.pop(); //将该节点弹出if(node.right != null) stack.push(node.right); //添加左节点stack.push(node); //添加中节点stack.push(null); //中间节点访问过,但是还没有处理,加入空节点标记if(node.left != null) stack.push(node.left); //添加右节点}else{stack.pop(); //弹出空节点node = stack.pop(); //取出栈中元素list.add(node.val);}}return list;}
}
  • 后序
class Solution {public List<Integer> postorderTraversal(TreeNode root) {List<Integer> list = new ArrayList<>();Stack<TreeNode> stack = new Stack<>();if(root != null) stack.push(root);while(!stack.isEmpty()){TreeNode node = stack.peek();if(node != null){node = stack.pop();stack.push(node);stack.push(null);if(node.right != null) stack.push(node.right);if(node.left != null) stack.push(node.left);}else{stack.pop();node = stack.pop();list.add(node.val);}}return list;}
}

分析

  • 可以看到使用空节点标记法,只需要修改两行代码就能写出不同的遍历代码

4、二叉树的层序遍历

学会二叉树的层序遍历,可以一口气打完以下十题:

  • 102.二叉树的层序遍历
  • 107.二叉树的层次遍历II
  • 199.二叉树的右视图
  • 637.二叉树的层平均值
  • 429.N叉树的层序遍历
  • 515.在每个树行中找最大值
  • 116.填充每个节点的下一个右侧节点指针
  • 117.填充每个节点的下一个右侧节点指针II
  • 104.二叉树的最大深度
  • 111.二叉树的最小深度

代码 102题

  • 迭代
class Solution {public List<List<Integer>> levelOrder(TreeNode root) {List<List<Integer>> list = new ArrayList<>();if(root == null) return list;Queue<TreeNode> queue = new LinkedList<>();queue.offer(root);while(!queue.isEmpty()){List<Integer> tempList = new ArrayList<>();int len = queue.size();while(len > 0){TreeNode node = queue.poll();tempList.add(node.val);if(node.left != null) queue.offer(node.left);if(node.right != null) queue.offer(node.right);len--;}list.add(tempList);}return list;}
}
  • 递归
class Solution {public List<List<Integer>> levelOrder(TreeNode root) {List<List<Integer>> list = new ArrayList<>();level(root,list,0);return list;}public void level(TreeNode node,List<List<Integer>> list,int depth){if(node == null) return;depth++;if(list.size() < depth){List<Integer> tempList = new ArrayList<>();list.add(tempList);}list.get(depth-1).add(node.val);level(node.left,list,depth);level(node.right,list,depth);}
}

分析

  • 迭代法借助了数据结构队列,先入先出。

226.翻转二叉树

leetcode链接
在这里插入图片描述

代码

  • 前序遍历
class Solution {public TreeNode invertTree(TreeNode root) {preOrderReverse(root);return root;}public void preOrderReverse(TreeNode node){if(node == null) return;TreeNode temp = node.left;node.left = node.right;node.right = temp;preOrderReverse(node.left);preOrderReverse(node.right);}
}
  • 后序遍历
class Solution {public TreeNode invertTree(TreeNode root) {preOrderReverse(root);return root;}public void preOrderReverse(TreeNode node){if(node == null) return;preOrderReverse(node.left);preOrderReverse(node.right);TreeNode temp = node.left;node.left = node.right;node.right = temp;}
}
  • BFS
class Solution {public TreeNode invertTree(TreeNode root) {if(root == null) return root;Queue<TreeNode> queue = new LinkedList<>();queue.offer(root);while(queue.size()>0){int size = queue.size();for(int i = 0;i < size;i++){TreeNode node = queue.poll();TreeNode temp = node.left;node.left = node.right;node.right = temp;if(node.left != null) queue.offer(node.left);if(node.right != null) queue.offer(node.right);}}return root;}
}
  • 统一法
class Solution {public TreeNode invertTree(TreeNode root) {if(root == null) return root;Stack<TreeNode> stack = new Stack<>();stack.push(root);while(!stack.isEmpty()){TreeNode node = stack.peek();if(node != null){stack.pop();if(node.right != null) stack.push(node.right);if(node.left != null) stack.push(node.left);stack.push(node);stack.push(null);}else{stack.pop();node = stack.pop();TreeNode temp = node.left;node.left = node.right;node.right = temp;}}return root;}
}

分析

  • 第一种递归的方式,只能写前序和后序,中序代码会导致有些节点反转了两次
  • 第二种BFS,也就是层序遍历
  • 第三种,统一的写法满足前中后序三种遍历方式

相关文章:

《代码随想录》--二叉树(一)

《代码随想录》--二叉树 第一部分 1、二叉树的递归遍历2、二叉树的迭代遍历3、统一风格的迭代遍历代码4、二叉树的层序遍历226.翻转二叉树 1、二叉树的递归遍历 前序遍历 中序遍历 后序遍历 代码 前序遍历 class Solution {public List<Integer> preorderTraversal(T…...

shell编程-数组与运算符详解(超详细)

文章目录 前言一、 Shell数组1. 声明和初始化数组2. 访问数组元素3. 数组长度4. 遍历数组5. 修改数组元素6. 删除数组元素7. 示例 二、Shell运算符1. 算术运算符1.1 加法运算符 ()1.2 减法运算符 (-)1.3 乘法运算符 (*)1.4 除法运算符 (/)1.5 取余运算符 (%) 2. 关系运算符2.1 …...

Vim入门

Vim使用入门 1.Vim编辑器的三种常用模式 一般模式&#xff1a;刚打开文件是它&#xff0c;从编辑模式按“ESC”退回的模式也是它。可以执行各种编辑操作&#xff0c;如移动光标、复制、粘贴、删除、查找替换等 ; 编辑模式&#xff1a;在一般模式下按下 i、I、a、A、o、O 等键…...

动态加载库

no_mangle 不要改标识符 首先是认识这个标注&#xff1a;mangle&#xff0c;英文的含义“撕裂、碾压”。我第一次把这个单次误以为是manage&#xff0c;说实话两个单词还挺像的。 RUS中函数或静态变量使用#[no_mangle]这个标注属性后&#xff0c;编译器就不会修改它们的名字了…...

React中渲染html结构---dangerouslySetInnerHTML

dangerouslySetInnerHTML胡子{}语法绑定的内容全部作为普通文本渲染&#xff0c;渲染html结构基于---dangerouslySetInnerHTMLdangerouslySetInnerHTML是React标签的一个属性&#xff0c;类似于vue的v-html有2个{{}},第一个{}代表jsx语法开始&#xff0c;第二个是代表dangerous…...

计网02-计算机网络参考模型

一、OSI七层参考模型 1、分层的思想 分层模型用于网络协议的设计方法&#xff0c;本质是将网络节点间复杂的通信问题分成若干简单的问题逐一解决&#xff0c;通过网络的层次去找问题&#xff0c;将复杂问题简单化。 2、OSI参考模型 由于早期计算机厂商使用的是私有的网络模…...

模块测试:确保软件质量的关键步骤

引言&#xff1a; 在软件开发过程中&#xff0c;模块测试是确保软件质量的关键环节。通过模块化的设计和测试方法&#xff0c;可以提高开发效率、降低错误率&#xff0c;并最终提供稳定可靠的软件产品。本文将介绍模块测试的概念、重要性以及实施步骤&#xff0c;帮助读者了解如…...

Postman接口测试之Postman常用的快捷键

作为一名IT程序猿&#xff0c;不懂一些工具的快捷方式&#xff0c;应该会被鄙视的吧。收集了一些Postman的快捷方式&#xff0c;大家一起动手操作~ 简单操作 xc 请求 操作MAC系统windows系统请求网址 ⌘L Ctrl L 保存请求 ⌘S Ctrl S 保存请求为 ⇧⌘S Ctrl Shift S发送…...

keil自动分配SDRAM空间设置使用

1.修改.sct文件 添加 RW_RAM1 0xC0400000 UNINIT 0x00400000 { ; RW data .ANY (SD_RAM1) 使用 #define LOCATION_ATTRIBUTE(name) __attribute__ ((section(name))) __attribute__ ((aligned(4)))uint8_t sdram_buf[0x100000] __attribute__ ((section("SD_RAM1")…...

TikTok获客怎么做?可以定制一个获客工具!

随着社交媒体的兴起&#xff0c;越来越多的企业开始将目光投向了短视频平台&#xff0c;TikTok作为其中的佼佼者&#xff0c;凭借其独特的算法和内容推荐机制&#xff0c;吸引了大量用户的关注。 那么&#xff0c;如何在TikTok上获取更多的客户呢?本文将为您揭秘TikTok获客的…...

数据结构(Chapter Two -02)—顺序表基本操作实现

在前一部分我们了解线性表和顺序表概念&#xff0c;如果有不清楚可以参考下面的博客&#xff1a; 数据结构(Chapter Two -01)—线性表及顺序表-CSDN博客 首先列出线性表的数据结构&#xff1a; #define MaxSize 50 //定义顺序表最大长度 typedef struct{ElemType data…...

SQL语句整理二--Mysql

文章目录 知识点梳理&#xff1a;1. mysql 中 in 和 exists 区别2. varchar 与 char 的区别 查看表结构&#xff1a;获取当前时间&#xff1a;查看建表语句&#xff1a;修改用户密码&#xff1a;查看所有用户&#xff1a;grant命令&#xff1a;判断当前数据库有多少连接数&…...

oracle与gbase8s迁移数据类型对照

声明&#xff1a;以下为笔者阅读gbase官方文档和oracle官方文档的理解&#xff0c;如有错误&#xff0c;敬请指正。oracle与gbase8s迁移数据类型对照及举例说明 最终结论&#xff1a;oracle与gbase8s数据类型对应关系关于单精度与双精度的区别关于定点与浮点定义的区别精度的定…...

Flink系列之:集合操作

Flink系列之&#xff1a;集合操作 一、集合操作二、UNION三、INTERSECT四、EXCEPT五、IN六、EXISTS 一、集合操作 适用于流、批操作 二、UNION UNION 和 UNION ALL 返回两个表中的数据。 UNION 会去重&#xff0c;UNION ALL 不会去重。 Flink SQL> create view t1(s) as…...

STL:string的常见用法

目录 赋值和连接&#xff1a; operator: 赋值操作符&#xff1a; assign(str): 将字符串赋值为另一个字符串&#xff1a; : 字符串连接操作符&#xff1a; 访问和检查&#xff1a; at(pos): 返回指定位置的字符&#xff0c;提供边界检查。 operator[]: 返回指定位置的字符…...

GBASE南大通用 ADO.NET 中的事务

GBASE南大通用 ADO.NET 中支持事务&#xff0c;可以使用GBASE南大通用Connection 对象的BeginTransaction 函数开始一个事务&#xff0c;并默认使用 ReadCommitted 模式初始化。 事务中可以对单个表执行多个操作&#xff0c;或者对多个表执行多个操作&#xff0c;在事务未提交…...

App(Android)ICP备案号查询——————高仿微信

&#x1f604; 个人主页&#xff1a;✨拉莫帅-CSDN博客✨&#x1f914; 博文&#xff1a;132篇&#x1f525; 原创&#xff1a;130篇&#xff0c;转载&#xff1a;2篇&#x1f525; 总阅读量&#xff1a;388923❤️ 粉丝量&#xff1a;112&#x1f341; 感谢点赞和关注 &#x…...

修改npm源码解决服务端渲染环境中localstorage报错read properties of undefined (reading getItem)

现象&#xff1a; 这个问题是直接指向了我使用的第三方库good-storage&#xff0c;这是一个对localStorage/sessionStorage做了简单封装的库&#xff0c;因为项目代码有一个缓存cache.ts有用到 原因分析&#xff1a; 从表象上看是storage对象找不到getItem方法&#xff0c; 但…...

Educational Codeforces Round 160 (Div. 2) A~C(D,E更新中...)

A.Rating Increase&#xff08;思维&#xff09; 题意&#xff1a; 给出一个仅包含数字的字符串 s s s&#xff0c;要求将该字符串按以下要求分成左右两部分 a , b a,b a,b&#xff1a; 两个数字均不包含前导 0 0 0 两个数字均大于 0 0 0 b > a b > a b>a 如果…...

【Maven-Helper】利用 Maven-Helper 解决依赖冲突问题

【Maven-Helper】利用 Maven-Helper 解决依赖冲突问题 1&#xff09;安装 Maven-Helper 插件2&#xff09;Maven Helper 插件使用方法3&#xff09;Idea-Maven 可视化依赖树 1&#xff09;安装 Maven-Helper 插件 这里我们已经安装过了&#xff0c;如果没有安装过&#xff0c;点…...

web vue 项目 Docker化部署

Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段&#xff1a; 构建阶段&#xff08;Build Stage&#xff09;&#xff1a…...

进程地址空间(比特课总结)

一、进程地址空间 1. 环境变量 1 &#xff09;⽤户级环境变量与系统级环境变量 全局属性&#xff1a;环境变量具有全局属性&#xff0c;会被⼦进程继承。例如当bash启动⼦进程时&#xff0c;环 境变量会⾃动传递给⼦进程。 本地变量限制&#xff1a;本地变量只在当前进程(ba…...

视频字幕质量评估的大规模细粒度基准

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用&#xff0c;因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型&#xff08;VLMs&#xff09;在字幕生成方面…...

ETLCloud可能遇到的问题有哪些?常见坑位解析

数据集成平台ETLCloud&#xff0c;主要用于支持数据的抽取&#xff08;Extract&#xff09;、转换&#xff08;Transform&#xff09;和加载&#xff08;Load&#xff09;过程。提供了一个简洁直观的界面&#xff0c;以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...

VTK如何让部分单位不可见

最近遇到一个需求&#xff0c;需要让一个vtkDataSet中的部分单元不可见&#xff0c;查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行&#xff0c;是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示&#xff0c;主要是最后一个参数&#xff0c;透明度…...

Element Plus 表单(el-form)中关于正整数输入的校验规则

目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入&#xff08;联动&#xff09;2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...

排序算法总结(C++)

目录 一、稳定性二、排序算法选择、冒泡、插入排序归并排序随机快速排序堆排序基数排序计数排序 三、总结 一、稳定性 排序算法的稳定性是指&#xff1a;同样大小的样本 **&#xff08;同样大小的数据&#xff09;**在排序之后不会改变原始的相对次序。 稳定性对基础类型对象…...

Caliper 配置文件解析:fisco-bcos.json

config.yaml 文件 config.yaml 是 Caliper 的主配置文件,通常包含以下内容: test:name: fisco-bcos-test # 测试名称description: Performance test of FISCO-BCOS # 测试描述workers:type: local # 工作进程类型number: 5 # 工作进程数量monitor:type: - docker- pro…...

毫米波雷达基础理论(3D+4D)

3D、4D毫米波雷达基础知识及厂商选型 PreView : https://mp.weixin.qq.com/s/bQkju4r6med7I3TBGJI_bQ 1. FMCW毫米波雷达基础知识 主要参考博文&#xff1a; 一文入门汽车毫米波雷达基本原理 &#xff1a;https://mp.weixin.qq.com/s/_EN7A5lKcz2Eh8dLnjE19w 毫米波雷达基础…...

根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的----NTFS源代码分析--重要

根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的 第一部分&#xff1a; 0: kd> g Breakpoint 9 hit Ntfs!ReadIndexBuffer: f7173886 55 push ebp 0: kd> kc # 00 Ntfs!ReadIndexBuffer 01 Ntfs!FindFirstIndexEntry 02 Ntfs!NtfsUpda…...