《代码随想录》--二叉树(一)
《代码随想录》--二叉树 第一部分
- 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编辑器的三种常用模式 一般模式:刚打开文件是它,从编辑模式按“ESC”退回的模式也是它。可以执行各种编辑操作,如移动光标、复制、粘贴、删除、查找替换等 ; 编辑模式:在一般模式下按下 i、I、a、A、o、O 等键…...

动态加载库
no_mangle 不要改标识符 首先是认识这个标注:mangle,英文的含义“撕裂、碾压”。我第一次把这个单次误以为是manage,说实话两个单词还挺像的。 RUS中函数或静态变量使用#[no_mangle]这个标注属性后,编译器就不会修改它们的名字了…...
React中渲染html结构---dangerouslySetInnerHTML
dangerouslySetInnerHTML胡子{}语法绑定的内容全部作为普通文本渲染,渲染html结构基于---dangerouslySetInnerHTMLdangerouslySetInnerHTML是React标签的一个属性,类似于vue的v-html有2个{{}},第一个{}代表jsx语法开始,第二个是代表dangerous…...

计网02-计算机网络参考模型
一、OSI七层参考模型 1、分层的思想 分层模型用于网络协议的设计方法,本质是将网络节点间复杂的通信问题分成若干简单的问题逐一解决,通过网络的层次去找问题,将复杂问题简单化。 2、OSI参考模型 由于早期计算机厂商使用的是私有的网络模…...
模块测试:确保软件质量的关键步骤
引言: 在软件开发过程中,模块测试是确保软件质量的关键环节。通过模块化的设计和测试方法,可以提高开发效率、降低错误率,并最终提供稳定可靠的软件产品。本文将介绍模块测试的概念、重要性以及实施步骤,帮助读者了解如…...

Postman接口测试之Postman常用的快捷键
作为一名IT程序猿,不懂一些工具的快捷方式,应该会被鄙视的吧。收集了一些Postman的快捷方式,大家一起动手操作~ 简单操作 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获客怎么做?可以定制一个获客工具!
随着社交媒体的兴起,越来越多的企业开始将目光投向了短视频平台,TikTok作为其中的佼佼者,凭借其独特的算法和内容推荐机制,吸引了大量用户的关注。 那么,如何在TikTok上获取更多的客户呢?本文将为您揭秘TikTok获客的…...

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

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

oracle与gbase8s迁移数据类型对照
声明:以下为笔者阅读gbase官方文档和oracle官方文档的理解,如有错误,敬请指正。oracle与gbase8s迁移数据类型对照及举例说明 最终结论:oracle与gbase8s数据类型对应关系关于单精度与双精度的区别关于定点与浮点定义的区别精度的定…...
Flink系列之:集合操作
Flink系列之:集合操作 一、集合操作二、UNION三、INTERSECT四、EXCEPT五、IN六、EXISTS 一、集合操作 适用于流、批操作 二、UNION UNION 和 UNION ALL 返回两个表中的数据。 UNION 会去重,UNION ALL 不会去重。 Flink SQL> create view t1(s) as…...
STL:string的常见用法
目录 赋值和连接: operator: 赋值操作符: assign(str): 将字符串赋值为另一个字符串: : 字符串连接操作符: 访问和检查: at(pos): 返回指定位置的字符,提供边界检查。 operator[]: 返回指定位置的字符…...
GBASE南大通用 ADO.NET 中的事务
GBASE南大通用 ADO.NET 中支持事务,可以使用GBASE南大通用Connection 对象的BeginTransaction 函数开始一个事务,并默认使用 ReadCommitted 模式初始化。 事务中可以对单个表执行多个操作,或者对多个表执行多个操作,在事务未提交…...

App(Android)ICP备案号查询——————高仿微信
😄 个人主页:✨拉莫帅-CSDN博客✨🤔 博文:132篇🔥 原创:130篇,转载:2篇🔥 总阅读量:388923❤️ 粉丝量:112🍁 感谢点赞和关注 &#x…...

修改npm源码解决服务端渲染环境中localstorage报错read properties of undefined (reading getItem)
现象: 这个问题是直接指向了我使用的第三方库good-storage,这是一个对localStorage/sessionStorage做了简单封装的库,因为项目代码有一个缓存cache.ts有用到 原因分析: 从表象上看是storage对象找不到getItem方法, 但…...

Educational Codeforces Round 160 (Div. 2) A~C(D,E更新中...)
A.Rating Increase(思维) 题意: 给出一个仅包含数字的字符串 s s s,要求将该字符串按以下要求分成左右两部分 a , b a,b a,b: 两个数字均不包含前导 0 0 0 两个数字均大于 0 0 0 b > a b > a b>a 如果…...

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

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...

51c自动驾驶~合集58
我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留,CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制(CCA-Attention),…...
进程地址空间(比特课总结)
一、进程地址空间 1. 环境变量 1 )⽤户级环境变量与系统级环境变量 全局属性:环境变量具有全局属性,会被⼦进程继承。例如当bash启动⼦进程时,环 境变量会⾃动传递给⼦进程。 本地变量限制:本地变量只在当前进程(ba…...

从WWDC看苹果产品发展的规律
WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...

Day131 | 灵神 | 回溯算法 | 子集型 子集
Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣(LeetCode) 思路: 笔者写过很多次这道题了,不想写题解了,大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...
macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用
文章目录 问题现象问题原因解决办法 问题现象 macOS启动台(Launchpad)多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显,都是Google家的办公全家桶。这些应用并不是通过独立安装的…...

ElasticSearch搜索引擎之倒排索引及其底层算法
文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...
关于 WASM:1. WASM 基础原理
一、WASM 简介 1.1 WebAssembly 是什么? WebAssembly(WASM) 是一种能在现代浏览器中高效运行的二进制指令格式,它不是传统的编程语言,而是一种 低级字节码格式,可由高级语言(如 C、C、Rust&am…...
Unit 1 深度强化学习简介
Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库,例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体,比如 SnowballFight、Huggy the Do…...

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)
船舶制造装配管理现状:装配工作依赖人工经验,装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书,但在实际执行中,工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...