代码随想录第十四天|二叉树part02--226.翻转二叉树、101.对称二叉树、104.二叉树的最大深度、111.二叉树的最小深度
资料引用:
226.翻转二叉树(226.翻转二叉树)
101.对称二叉树(101.对称二叉树)
104.二叉树的最大深度(104.二叉树的最大深度)
111.二叉树的最小深度(111.二叉树的最小深度)
226.翻转二叉树(226.翻转二叉树)
题目分析:
给定一棵二叉树的根节点root,翻转二叉树,使每一棵子树的根节点的左右孩子交换,最后返回根节点。
解题重点:
选择合适的遍历方式以便于处理。
解题思路:
考虑采取递归的遍历方式进行处理,使用前序或后序遍历皆可。
- 递归函数的参数:待处理的子树根节点
- 递归函数的返回值:处理完毕的子树根节点
- 递归函数的终止条件:遇到空节点直接返回
- 递归函数的单层递归逻辑:
-
- 前序遍历:终止条件判断、swap左右孩子,递归进入左孩子,递归进入右孩子,返回当前根节点
- 后序遍历:终止条件判断、递归进入左孩子,递归进入右孩子,swap左右孩子,返回当前根节点
注意:
为什么不使用中序遍历?
因为中序遍历是左中右,先完成对左子树的翻转,再将左右子树互换,此时若再对当前的右子树做翻转,实际上是对互换前的、已经完成翻转的“前左子树”做翻转。
修改方式:左中“左”
总结反思:
需要把握好不同遍历方式下处理操作的顺序,尤其是前(后)序和中序之间的区别。
class Solution {public TreeNode invertTree(TreeNode root) {if (root == null) return root;swap_Kids(root);invertTree(root.left);invertTree(root.right);return root;}public void swap_Kids (TreeNode root) {TreeNode tmpNode = root.left;root.left = root.right;root.right = tmpNode;return;}
}
101.对称二叉树(101.对称二叉树)
题目分析:
给定一个二叉树的根节点root,判断其是否为轴对称的,即翻转后树的节点值是否不变(包括空值)。
解题重点:
选择合适的遍历方式,方便比较。
简单思路:
先遍历取节点值,包括空值,用StringBuilder存储(便于存储空值),
再翻转二叉树,
最后用相同的方式遍历取节点值,实时比较是否与第一步得到的字符数组相同。
此处采取前序遍历。
class Solution {public boolean isSymmetric(TreeNode root) {if (root == null) return true;StringBuilder sb1 = new StringBuilder();StringBuilder sb2 = new StringBuilder();preOrder(root, sb1);invertTree(root);preOrder(root, sb2);return sb1.toString().equals(sb2.toString());}public void preOrder(TreeNode root, StringBuilder sb){if(root == null) {sb.append("\0");return;}sb.append(Integer.toString(root.val));preOrder(root.left, sb);preOrder(root.right, sb);}public TreeNode invertTree(TreeNode root) {if (root == null) return root;swap_Kids(root);invertTree(root.left);invertTree(root.right);return root;}public void swap_Kids (TreeNode root) {TreeNode tmpNode = root.left;root.left = root.right;root.right = tmpNode;return;}
}
推荐思路:
比较的不是二叉树的左右节点,比较的是根节点的左子树和右子树是不是相互翻转的,即比较对象是左右子树。
因此,在递归遍历过程中,要同时遍历两棵树。
由翻转的特性,我们定义:靠近中轴的是里侧节点,远离中轴的外侧节点。
选择“后序遍历”:通过递归函数的返回值判断两个子树之间的内侧节点和外侧节点是否相等。
准确来说:对两个子树的遍历应当分别为左右中和右左中。
定义递归比较函数compare如下:
-
- 递归函数的参数:左右子树节点
- 递归函数的返回值:布尔值
- 确定终止条件:
-
-
- 节点为空的情况:
-
-
-
-
- 左空,右非空,return false
- 左非空,右空,return false
- 左右都为空,对称,return true
-
-
-
-
- 节点非空的情况:
-
-
-
-
- 左右都非空,节点值不同false,相同继续
-
-
-
- 递归函数的单层递归逻辑:处理 左右节点都不为空,且数值相同的情况
-
-
- 递归比较左孩子的左孩子 和 右孩子的右孩子(外侧节点)
- 递归比较左孩子的右孩子 和 右孩子的左孩子(里侧节点)
- 取前两者的逻辑并,返回该值。
-
class Solution {public boolean isSymmetric(TreeNode root) {if (root == null) return true;return compareLR(root.left, root.right);}public boolean compareLR(TreeNode left, TreeNode right) {// 首先排除节点为空的情况if (left == null && right != null) return false;else if (left != null && right == null) return false;else if (left == null && right == null) return true;// 然后排除节点不为空时,两节点值不相等的情况else if (left.val != right.val) return false;// 递归比较外侧节点和里侧节点,取逻辑并boolean outside = compareLR(left.left, right.right);boolean inside = compareLR(left.right, right.left);boolean isSame = outside && inside;return isSame;}
}
总结反思:
学会根据任务需求灵活调整遍历方式进行比较。
递归中的三要素需要在掌握的基础上根据实际情况来调整完善,尤其是终止条件的合理设定,非常重要。
104.二叉树的最大深度(104.二叉树的最大深度)
题目分析:
给定一个二叉树,返回其最大深度。
解题重点:
对于一个二叉树,求其最大深度,则在递归遍历过程中增加deep参数的传递。
注意:
最大深度定义为:从根节点到最远叶子节点的最长路径上的节点数,因此最小深度从1开始(根节点不为空,若为空返回0)。
解题思路:
构造递归函数getMaxDepth如下:
- 递归函数的参数:节点node,当前深度deep
- 递归函数的返回值:最终深度deep,整型
- 递归函数的终止条件:遇到空节点,返回当前deep
- 递归函数的单层递归逻辑:节点为空,返回deep。节点不为空,deep++,递归查询左子树的最大深度left_depth和右子树的最大深度right_depth,取较大者返回。
总结:
注意通过递归函数的参数传递,实现当前深度deep的记录,并注意比较左右子树取较大者。
class Solution {public int maxDepth(TreeNode root) {return getMaxDepth(root, 0);}public int getMaxDepth(TreeNode root, int deep) {if (root == null) return deep;deep++;int left_depth = getMaxDepth(root.left, deep);int right_depth = getMaxDepth(root.right, deep);return left_depth > right_depth ? left_depth : right_depth;}
}
111.二叉树的最小深度(111.二叉树的最小深度)
题目分析:
给定一个二叉树的根节点root,找出其最小深度。
注意:
最小深度的定义:从根节点到最近叶子结点的最短路径上的节点数。
解题重点:
需要排除左(右)子树为空的这条路径
解题思路与优化:
后序遍历:
- 自底向上求高度(等价于求深度),
- 终止条件是遇到空节点时返回0(叶子节点为从1开始)
- 通过递归的逐级返回进行自增即可
- 注意排除节点为空的情况,不可作为最小深度比较对象
前序遍历:
- 自顶向下求深度
- 终止条件是遇到空节点时不自增,直接返回当前积累深度deep
- 通过递归返回的是最底层的计算结果,是通过逐级向下递归时自增的
- 需要额外增加参数--当前深度deep,因此需要构造新的递归函数
- 相较后序并不简洁,但也可实现。
层序遍历(迭代法):
- 层序遍历通过队列实现
- 需要注意的是:只有当左右孩子都为空,才说明是抵达叶子节点,否则继续
- 首次抵达叶子结点时,由于层序遍历是从上往下遍历,所以正是最近叶子节点
总结反思:
理解前序遍历和后序遍历的“方向”区别,根据实际情景选取适合的遍历方式。
理解题意很重要,不要经验主义下判断~
/*后序遍历 递归法*/
class Solution {/*该解法实际是后序遍历,相当于求最小高度,等价于求最小深度 */public int minDepth(TreeNode root) {if (root == null) return 0;int leftDepth = minDepth(root.left);int rightDepth = minDepth(root.right);if (root.left == null) return rightDepth+1;if (root.right == null) return leftDepth+1;return leftDepth < rightDepth ? leftDepth+1 : rightDepth+1;}
}
/*前序遍历 递归法*/
class Solution {public int minDepth(TreeNode root) {return getMinDepth(root, 0);}public int getMinDepth(TreeNode root, int deep) {if (root == null) return deep;deep++;int left_depth = 0;int right_depth = 0;if (root.left == null) return getMinDepth(root.right, deep);else if (root.right == null) return getMinDepth(root.left, deep);left_depth = getMinDepth(root.left, deep);right_depth = getMinDepth(root.right, deep);return left_depth < right_depth ? left_depth : right_depth;}
}
/*层序遍历 迭代法*/
class Solution {public int minDepth(TreeNode root) {if (root == null) {return 0;}Deque<TreeNode> deque = new ArrayDeque<>();deque.offer(root);int depth = 0;while (!deque.isEmpty()) {int size = deque.size();depth++;for (int i = 0; i < size; i++) {TreeNode poll = deque.poll();if (poll.left == null && poll.right == null) {// 因为从上往下遍历,所以是最近叶子结点,该值就是最小值,直接返回depthreturn depth;}if (poll.left != null) {deque.offer(poll.left);}if (poll.right != null) {deque.offer(poll.right);}}}return depth;}
}
相关文章:
代码随想录第十四天|二叉树part02--226.翻转二叉树、101.对称二叉树、104.二叉树的最大深度、111.二叉树的最小深度
资料引用: 226.翻转二叉树(226.翻转二叉树) 101.对称二叉树(101.对称二叉树) 104.二叉树的最大深度(104.二叉树的最大深度) 111.二叉树的最小深度(111.二叉树的最小深度)…...
vue基础之7:天气案例、监视属性、深度监视、监视属性(简写)
欢迎来到“雪碧聊技术”CSDN博客! 在这里,您将踏入一个专注于Java开发技术的知识殿堂。无论您是Java编程的初学者,还是具有一定经验的开发者,相信我的博客都能为您提供宝贵的学习资源和实用技巧。作为您的技术向导,我将…...
JS实现高效导航——A*寻路算法+导航图简化法
一、如何实现两点间路径导航 导航实现的通用步骤,一般是: 1、网格划分 将地图划分为网格,即例如地图是一张图片,其像素为1000*1000,那我们将此图片划分为各个10*10的网格,从而提高寻路算法的计算量。 2、标…...
Spring Authorization Server登出说明与实践
本章内容概览 Spring Security提供的/logout登出接口做了什么与如何自定义。Spring Authorization Server提供的/connect/logout登出接口做了什么与如何自定义。Spring Authorization Server提供的/oauth2/revoke撤销token接口做了什么与如何自定义。 前言 既然系统中有登录功…...
浏览器报错 | 代理服务器可能有问题,或地址不正确
1 问题描述 Windows连网情况下,浏览器访问地址显示“你尚未连接,代理服务器可能有问题,或地址不正确。”出现如下画面: 2 解决方法 途径1 控制面板-->网络与internet-->internet选项-->Internet属性-->连接-->…...
泷羽sec:shell编程(9)不同脚本的互相调用和重定向操作
声明: 学习视频来自B站up主 泷羽sec 有兴趣的师傅可以关注一下,如涉及侵权马上删除文章,笔记只是方便各位师傅的学习和探讨,文章所提到的网站以及内容,只做学习交流,其他均与本人以及泷羽sec团队无关&#…...
Milvus×OPPO:如何构建更懂你的大模型助手
01. 背景 AI业务快速增长下传统关系型数据库无法满足需求。 2024年恰逢OPPO品牌20周年,OPPO也宣布正式进入AI手机的时代。超千万用户开始通过例如通话摘要、新小布助手、小布照相馆等搭载在OPPO手机上的应用体验AI能力。 与传统的应用不同的是,在AI驱动的…...
单片机几大时钟源
在单片机中,MSI、HSI和HSE通常指的是用于内部晶振配置的不同功能模块: MSI (Master Oscillator System Interface):这是最低级的一种时钟源管理单元,它控制着最基本的系统时钟(SYSCLK),一般由外…...
reverse学习总结(12)
一.[FlareOn4]IgniteMe1 https://files.buuoj.cn/files/02b39b8efca02367af23aa279c81cbec/attachment.zip 根据汇编语言分析 查看需要返回为1的函数 int sub_401050() {int v1; // [esp0h] [ebp-Ch]int i; // [esp4h] [ebp-8h]unsigned int j; // [esp4h] [ebp-8h]char v4; …...
基于“微店 Park”模式下 2+1 链动模式商城小程序的创新发展与应用研究
摘要:本文以“微店 Park”从“开店工具”向“众创平台”的转型为背景,深入探讨 21 链动模式商城小程序在该平台情境下的应用潜力与创新发展路径。通过剖析“微店 Park”的运营模式,包括灵活承租、低成本入驻、多元流量引流等特点,…...
C++11:【列表初始化】【右值引用和移动语义】
目录 一.列表初始化 1.1 C98传统的{} 1.2C11中的{} 1.3C中的std::initializer_list 二.右值引用和移动语义 2.1左值和右值 2.2左值引用和右值引用 2.3引用延长生命周期 2.4左值和右值的参数匹配 2.5右值引用和移动语义的使用场景 2.5.1左值引用主要使用场景 2.5.2移…...
Zookeeper的通知机制是什么?
大家好,我是锋哥。今天分享关于【Zookeeper的通知机制是什么?】面试题。希望对大家有帮助; Zookeeper的通知机制是什么? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 Zookeeper的通知机制主要通过Watcher实现,它是Zookeeper客…...
嵌入式蓝桥杯学习1 电量LED
cubemx配置 1.新建一个STM32G431RBT6文件 2.在System-Core中点击SYS,找到Debug(设置为Serial Wire) 3.在System-Core中点击RCC,找到High Speed Clock(设置为Crystal/Ceramic Resonator) 4.打开Clock Configuration ࿰…...
bsmap输出结果解释
关于, , -, --的解释 对应着参考基因组的正链(有义链,非模板链,即hg38的序列,watson链); -代表正链的互补链(正常情况下正链的互补链是负链,但在重硫酸盐处理后正链和负链并不互补…...
【java-数据结构篇】揭秘 Java LinkedList:链表数据结构的 Java 实现原理与核心概念
我的个人主页 我的专栏:Java-数据结构,希望能帮助到大家!!!点赞❤ 收藏❤ 目录 1. Java LinkedList 基础 1.1 LinkedList 简介 1.2 LinkedList 的实现原理 1.3 LinkedList 与 ArrayList 的区别 2. 链表基础 2.1 链…...
macOS运行amd64的镜像
在macOS上运行amd64(x86_64)架构的镜像,通常通过虚拟化或仿真工具来实现。例如,如果你使用的是基于Apple Silicon(M1或M2等)芯片的Mac,那么你的处理器是ARM架构的,而amd64是x86架构&…...
轻量的基于图结构的RAG方案LightRAG
LightRAG出自2024年10月的论文《LIGHTRAG: SIMPLE AND FASTRETRIEVAL-AUGMENTED GENERATION》(github),也是使用图结构来索引和搜索相关文本。 LightRAG作者认为已有的RAG系统有如下两个限制,导致难以回答类似"How does the rise of electric vehi…...
计算机的错误计算(一百七十三)
摘要 给定多项式 在 MATLAB 中计算 的值。输出是错误结果。 例1. 已知 计算 直接贴图吧: 这样,MATLAB 输出了错误结果。因为准确值为 0.2401e-16 . 注:可参看计算机的错误计算(六)。...
【力扣】—— 二叉树的前序遍历、字典序最小回文串
Hi~!这里是奋斗的明志,很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎 ~~ 🌱🌱个人主页:奋斗的明志 🌱🌱所属专栏:数据结构 📚本系列文章为个人学…...
linux替换更高版本gcc
实际使用时对与gcc版本有很多要求, 需要在centos上安装更高版本的gcc 1、安装centos-release-scl sudo yum install centos-release-scl2、安装devtoolset,注意,如果想安装7.版本的,就改成devtoolset-7-gcc,以此类推 sudo yum …...
树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频
使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...
【JavaEE】-- HTTP
1. HTTP是什么? HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议,HTTP是基于TCP协议的一种应用层协议。 应用层协议:是计算机网络协议栈中最高层的协议,它定义了运行在不同主机上…...
【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密
在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...
ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放
简介 前面两期文章我们介绍了I2S的读取和写入,一个是通过INMP441麦克风模块采集音频,一个是通过PCM5102A模块播放音频,那如果我们将两者结合起来,将麦克风采集到的音频通过PCM5102A播放,是不是就可以做一个扩音器了呢…...
sqlserver 根据指定字符 解析拼接字符串
DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...
【git】把本地更改提交远程新分支feature_g
创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...
相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...
汇编常见指令
汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX(不访问内存)XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...
华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建
华为云FlexusDeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色,华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型,能助力我们轻松驾驭 DeepSeek-V3/R1,本文中将分享如何…...
Swagger和OpenApi的前世今生
Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章,二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑: 🔄 一、起源与初创期:Swagger的诞生(2010-2014) 核心…...
