代码随想录第十四天|二叉树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 …...

Linux 文件类型,目录与路径,文件与目录管理
文件类型 后面的字符表示文件类型标志 普通文件:-(纯文本文件,二进制文件,数据格式文件) 如文本文件、图片、程序文件等。 目录文件:d(directory) 用来存放其他文件或子目录。 设备…...

visual studio 2022更改主题为深色
visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中,选择 环境 -> 常规 ,将其中的颜色主题改成深色 点击确定,更改完成...
Frozen-Flask :将 Flask 应用“冻结”为静态文件
Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是:将一个 Flask Web 应用生成成纯静态 HTML 文件,从而可以部署到静态网站托管服务上,如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...
【AI学习】三、AI算法中的向量
在人工智能(AI)算法中,向量(Vector)是一种将现实世界中的数据(如图像、文本、音频等)转化为计算机可处理的数值型特征表示的工具。它是连接人类认知(如语义、视觉特征)与…...
CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云
目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...
爬虫基础学习day2
# 爬虫设计领域 工商:企查查、天眼查短视频:抖音、快手、西瓜 ---> 飞瓜电商:京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空:抓取所有航空公司价格 ---> 去哪儿自媒体:采集自媒体数据进…...
LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》
这段 Python 代码是一个完整的 知识库数据库操作模块,用于对本地知识库系统中的知识库进行增删改查(CRUD)操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 with_session 实现数据库会话管理。 📘 一、整体功能概述 该模块…...

使用LangGraph和LangSmith构建多智能体人工智能系统
现在,通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战,比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...
Go 并发编程基础:通道(Channel)的使用
在 Go 中,Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式,用于在多个 Goroutine 之间传递数据,从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...
NPOI操作EXCEL文件 ——CAD C# 二次开发
缺点:dll.版本容易加载错误。CAD加载插件时,没有加载所有类库。插件运行过程中用到某个类库,会从CAD的安装目录找,找不到就报错了。 【方案2】让CAD在加载过程中把类库加载到内存 【方案3】是发现缺少了哪个库,就用插件程序加载进…...