当前位置: 首页 > 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;点…...

在QT中将多个项目(同代码不同ui和资源文件)合并

Linux下的qt环境 我现在有三个项目&#xff0c;代码一模一样&#xff0c;只有UI文件和资源文件不同现在想要合并代码 后期好上传在git 仅需要一个分支 更好管理将随行 康养 采图三个项目代码合并 思路是这样的 将每个项目都分类打包区分开我是在康养这个项目的基础上合…...

对 OS:TEP 的 MLFQ 策略的一点思考

1.SJF 调度算法SJF 没啥好说的, 书上讲的很清楚了, SJF 就是最短任务优先原则, 其设计初衷是想解决 FIFO 的糟糕的周转时间的问题.但是, 正如书上所说, 这玩意主打一个秩序井然, 只能处理所有任务同时到队列的情况, 要是某堆进程不按这套路出牌, 那 SJF 立马完蛋, 书上就有一个…...

视频PPT提取终极指南:3步从视频中智能提取演示文稿

视频PPT提取终极指南&#xff1a;3步从视频中智能提取演示文稿 【免费下载链接】extract-video-ppt extract the ppt in the video 项目地址: https://gitcode.com/gh_mirrors/ex/extract-video-ppt 你是否曾经需要从视频中提取PPT内容&#xff0c;却苦于手动截图效率低…...

电赛E题三子棋:我是如何用Open MV色块识别替代矩形识别,搞定棋盘定位的?

电赛E题三子棋&#xff1a;OpenMV色块识别技术实战解析 从矩形识别到色块识别的技术转型 在电子设计竞赛的视觉识别任务中&#xff0c;棋盘定位一直是个经典难题。最初我们团队采用了官方推荐的矩形识别方案&#xff0c;但实际调试中遇到了诸多挑战&#xff1a; 识别率不稳定&a…...

Ubuntu纯键盘操作全攻略:从入门到精通(附常用快捷键速查表)

Ubuntu纯键盘操作全指南&#xff1a;释放效率革命的终极手册 在数字工作流中&#xff0c;每一次伸手去摸鼠标都意味着思维的中断和效率的流失。Ubuntu作为最受欢迎的Linux发行版之一&#xff0c;其键盘操作体系之丰富远超多数用户的想象——从简单的窗口切换到底层系统调试&…...

Windows系统维护新体验:告别繁琐手动操作,用WinUtil一键搞定所有

Windows系统维护新体验&#xff1a;告别繁琐手动操作&#xff0c;用WinUtil一键搞定所有 【免费下载链接】winutil Chris Titus Techs Windows Utility - Install Programs, Tweaks, Fixes, and Updates 项目地址: https://gitcode.com/GitHub_Trending/wi/winutil 你是…...

手把手搭建基于Kintex UltraScale+的Cameralink图像处理系统:从LVDS解码到GTY输出HDMI的完整Vivado工程解析

手把手搭建基于Kintex UltraScale的Cameralink图像处理系统&#xff1a;从LVDS解码到GTY输出HDMI的完整Vivado工程解析 在工业视觉和医疗影像领域&#xff0c;Cameralink接口凭借其高带宽和低延迟特性&#xff0c;依然是许多高端相机的首选接口方案。而Xilinx的Kintex UltraSca…...

Qwen3.5-4B-Claude-Opus入门必看:中文逻辑推理助手Web镜像快速上手

Qwen3.5-4B-Claude-Opus入门必看&#xff1a;中文逻辑推理助手Web镜像快速上手 1. 模型概述 Qwen3.5-4B-Claude-4.6-Opus-Reasoning-Distilled-GGUF是一个专为中文逻辑推理优化的AI助手模型。它基于Qwen3.5-4B架构&#xff0c;通过蒸馏训练强化了结构化分析、分步骤回答以及代…...

网络爬虫主流思路及反爬破解技术应用(新手速成)

‌网络爬虫的主流思路‌是模拟浏览器行为自动化抓取网页数据&#xff0c;而‌反爬破解技术‌则通过代理IP、请求伪装、动态渲染处理等方式绕过网站防护机制&#xff0c;实现稳定高效的数据采集 。一、主流爬虫技术思路 1.‌请求模拟与数据提取‌ 使用 requests 或 urllib 构建H…...

PDFMathTranslate:突破语言障碍的学术文档翻译终极解决方案

PDFMathTranslate&#xff1a;突破语言障碍的学术文档翻译终极解决方案 【免费下载链接】PDFMathTranslate PDF scientific paper translation with preserved formats - 基于 AI 完整保留排版的 PDF 文档全文双语翻译&#xff0c;支持 Google/DeepL/Ollama/OpenAI 等服务&…...