【LeetCode每日一题】226. 翻转二叉树 101. 对称二叉树

每日一题

  • 226. 翻转二叉树
    • 题目
    • 总体思路
    • 代码
  • 101. 对称二叉树
    • 题目
    • 总体思路
    • 代码
    • 知识点

2025.9.5

226. 翻转二叉树

题目

给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。

示例 1:
在这里插入图片描述
输入:root = [4,2,7,1,3,6,9]
输出:[4,7,2,9,6,3,1]

示例 2:
在这里插入图片描述
输入:root = [2,1,3]
输出:[2,3,1]

示例 3:

输入:root = []
输出:[]

提示:

树中节点数目范围在 [0, 100] 内
-100 <= Node.val <= 100

总体思路

使用递归的深度优先搜索 DFS方法来翻转二叉树。其核心思想是:

  1. 递归地翻转左子树
  2. 递归地翻转右子树
  3. 交换当前节点的左右子节点
  4. 基础情况:当节点为空时,直接返回(递归终止条件)

这种后序遍历的方式确保在交换当前节点的子节点之前,其左右子树都已经被正确翻转。

时间复杂度与空间复杂度

时间复杂度:O(n)

  • 每个节点恰好被访问一次,n为二叉树中的节点数量
  • 每个节点进行常数时间的操作(交换指针)

空间复杂度:O(h),其中h是树的高度

  • 空间复杂度主要由递归调用栈的深度决定
  • 在最坏情况下(树退化为链表),h = n,空间复杂度为O(n)
  • 在最好情况下(平衡二叉树),h = logn,空间复杂度为O(logn)
  • 平均情况下,空间复杂度为O(h)

代码

golang

/*** Definition for a binary tree node.* type TreeNode struct {*     Val int*     Left *TreeNode*     Right *TreeNode* }*/
func invertTree(root *TreeNode) *TreeNode {if root == nil {return root}root.Left = invertTree(root.Left)root.Right = invertTree(root.Right)root.Left, root.Right = root.Right, root.Leftreturn root
}
/*** Definition for a binary tree node.* type TreeNode struct {*     Val int*     Left *TreeNode*     Right *TreeNode* }*/
func invertTree(root *TreeNode) *TreeNode {// 基础情况:如果当前节点为空,直接返回// 这是递归的终止条件,空节点不需要翻转if root == nil {return root}// 递归地翻转左子树// 将左子树完全翻转后,返回翻转后的左子树根节点root.Left = invertTree(root.Left)// 递归地翻转右子树// 将右子树完全翻转后,返回翻转后的右子树根节点root.Right = invertTree(root.Right)// 交换当前节点的左右子节点// 使用Go的多重赋值特性,不需要临时变量root.Left, root.Right = root.Right, root.Left// 返回翻转后的当前子树根节点return root
}

101. 对称二叉树

题目

给你一个二叉树的根节点 root , 检查它是否轴对称。

示例 1:
在这里插入图片描述
输入:root = [1,2,2,3,4,4,3]
输出:true

示例 2:
在这里插入图片描述
输入:root = [1,2,2,null,3,null,3]
输出:false

提示:

树中节点数目在范围 [1, 1000] 内
-100 <= Node.val <= 100

进阶:你可以运用递归和迭代两种方法解决这个问题吗?

总体思路

这段代码使用**广度优先搜索(BFS)**的方法来判断二叉树是否轴对称(镜像对称)。其核心思想是:

  1. 将需要比较的节点成对放入队列中(左子树的左节点 vs 右子树的右节点,左子树的右节点 vs 右子树的左节点)
  2. 每次从队列中取出一对节点进行比较
  3. 如果所有对应的节点对都满足镜像关系,则二叉树是对称的

时间复杂度与空间复杂度

时间复杂度:O(n)

  • 每个节点最多被访问一次,n为二叉树中的节点数量
  • 每个节点进行常数时间的比较操作

空间复杂度:O(n)

  • 在最坏情况下(完全二叉树),队列中最多会存储约n/2个节点对
  • 空间复杂度主要由队列的大小决定

代码

golang

/*** Definition for a binary tree node.* type TreeNode struct {*     Val int*     Left *TreeNode*     Right *TreeNode* }*/
func isSymmetric(root *TreeNode) bool {if root == nil {return true}type pair struct{l, r *TreeNode}q := []pair{{root.Left, root.Right}}for len(q) > 0 {p := q[0]q = q[1:]left, right := p.l, p.rif left == nil && right == nil {continue}if left == nil || right == nil {return false}if left.Val != right.Val {return false}q = append(q,pair{left.Left,right.Right})q = append(q, pair{left.Right, right.Left})}return true
}
package maintype TreeNode struct {Val   intLeft  *TreeNodeRight *TreeNode
}// isSymmetric 判断二叉树是否轴对称(镜像对称)
func isSymmetric(root *TreeNode) bool {// 如果根节点为空,空树被认为是对称的if root == nil {return true}// 定义pair结构体来存储需要比较的一对节点// l: 左子树中的某个节点,r: 右子树中对应的镜像节点type pair struct{ l, r *TreeNode }// 初始化队列,首先将根节点的左右子节点作为第一对需要比较的节点q := []pair{{root.Left, root.Right}}// 当队列不为空时循环处理for len(q) >  {// 从队列头部取出一对节点p := q[0]q = q[1:]  // 移除队列头部元素left, right := p.l, p.r// 如果两个节点都为空,说明对称,继续检查其他节点对if left == nil && right == nil {continue}// 如果只有一个节点为空,另一个不为空,说明不对称if left == nil || right == nil {return false}// 如果两个节点都不为空,但值不相等,说明不对称if left.Val != right.Val {return false}// 将下一层需要比较的节点对加入队列:// 1. 左节点的左子节点 vs 右节点的右子节点(外侧比较)// 2. 左节点的右子节点 vs 右节点的左子节点(内侧比较)q = append(q, pair{left.Left, right.Right})q = append(q, pair{left.Right, right.Left})}// 如果所有节点对都通过检查,说明二叉树是对称的return true
}

知识点

q := []pair{{root.Left, root.Right}}

这一行是 Go 语言里“构造切片并初始化第一个元素”的写法,拆开来看就明白了:

  1. []pair{ ... }
    表示创建一个元素类型为 pair 的切片(slice)。
  2. {{root.Left, root.Right}}
    切片里只放 一个元素,这个元素又是一个 pair 结构体,所以用两层花括号
    • 外层 {} 是“切片字面量”;
    • 内层 {} 是“结构体字面量”,给 pair 的字段 lr 分别赋值为 root.Leftroot.Right

等价于:

q := make([]pair, 0, 1)
q = append(q, pair{l: root.Left, r: root.Right})

只是第一种写法更简洁,常用来一次性初始化切片。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/95704.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/95704.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【RNN-LSTM-GRU】第三篇 LSTM门控机制详解:告别梯度消失,让神经网络拥有长期记忆

深入剖析LSTM的三大门控机制&#xff1a;遗忘门、输入门、输出门&#xff0c;通过直观比喻、数学原理和代码实现&#xff0c;彻底理解如何解决长期依赖问题。1. 引言&#xff1a;为什么需要LSTM&#xff1f;在上一篇讲解RNN的文章中&#xff0c;我们了解到​​循环神经网络&…

残差去噪扩散模型

论文题目:Residual Denoising Diffusion Models(残差去噪扩散模型) 会议:CVPR2024 摘要:残差去噪扩散模型(RDDM)是一种新的双重扩散过程,它将传统的单一去噪扩散过程解耦为残差扩散和噪声扩散。这种双重扩散框架通过引入残差,将基于去噪的扩散模型扩展为一种统一的、可…

MySQL与ES索引区别

MySQL与ES索引区别 MySQL索引像字典目录&#xff0c;ES索引更像整个图书馆的书籍分类系统。 关键限制&#xff1a;MySQL单表索引大小影响写性能&#xff0c;ES的分片数创建后不能改。 比如MySQL的“行”对应ES的“文档”&#xff0c;MySQL的“表”类似ES的“索引”概念。 MySQL…

vue3图标终极方案【npm包推荐】vue3-icon-sui(含源码详解)

简介 为彻底实现 vue3 项目图标自由&#xff0c;特开发此 npm包 vue3-icon-sui&#xff0c;全品类图标&#xff0c;通通支持&#xff01; iconify 图标svg 图标font-class 图标 安装 npm i vue3-icon-sui -S使用 按需导入 任意页面中 import myIcon from "vue3-icon-su…

redis----持久化

Redis 提供了两种主要的持久化机制&#xff0c;用于将内存中的数据保存到磁盘&#xff0c;以防止服务器重启或故障导致数据丢失。这两种机制分别是 RDB&#xff08;Redis Database&#xff09;和 AOF&#xff08;Append Only File&#xff09;。1. RDB 持久化RDB 是 Redis 默认…

Docker快速部署Mongodb主副本集实践

系列文章目录 第一章 Mongodb的主副本集 文章目录系列文章目录前言一、Mongodb基础介绍数据库&#xff08;Database&#xff09;集合&#xff08;Collection&#xff09;文档&#xff08;Document&#xff09;BSON&#xff08;Binary JSON&#xff09;_id&#xff08;主键&…

FC平台安装Windows Server2016并连接V6存储

创建 windows server2016 上传ISO创建虚拟机安装OS 加载光盘挂载成功之后&#xff0c;重启虚拟机重启之后VNC登录即可。在FC上安装windows&#xff0c;安装完成后&#xff0c;必须安装tools工具&#xff0c;不然没有虚拟网卡&#xff0c;无法配置ip地址。Windows主机安装toolsW…

农业XR数字融合工作站,赋能农业专业实践学习

随着数字技术与农业的深度融合&#xff0c;农业专业XR数字融合工作站为农业专业学生提供了沉浸式、交互式的学习体验。农业专业XR数字融合工作站作为集PC、VR、MR技术于一体的软硬件集成平台&#xff0c;通过虚拟仿真、数字孪生等技术手段&#xff0c;有效解决了传统农业教育中…

积分球的使用——简易版

这篇写的比较杂。积分球的功能积分球——测量灯具等光源的总光通量、光效、色温、显色指数等参数。使用方法1.开启积分球系统&#xff08;探测器、光度计、光谱仪&#xff09;&#xff0c;充分预热&#xff08;15-30分钟&#xff09;&#xff0c;使得电子设备稳定&#xff0c;减…

[光学原理与应用-435]:晶体光学 - 晶体的结构-基元/原胞/晶胞/点阵

晶体的结构可通过基元、原胞、晶胞和点阵四个核心概念进行系统描述&#xff0c;它们共同揭示了晶体中原子排列的周期性与对称性规律&#xff0c;具体如下&#xff1a;1. 基元&#xff08;Structure Motif&#xff09;定义&#xff1a;基元是晶体中重复排列的最小结构单元&#…

电脑音频录制 | 系统麦克混录 / 系统声卡直录 | 方法汇总 / 常见问题

注&#xff1a;本文为 “电脑音频录制 ” 相关合辑。 英文引文&#xff0c;机翻未校。 未整理去重&#xff0c;如有内容异常&#xff0c;请看原文。 How to Record Computer Audio in 6 Free Ways 如何用 6 种免费方式录制电脑音频 Sponsored by EaseUS Nov 28, 2023 4:34 a…

2025高教社国赛数学建模竞赛B题完整参考论文(含模型和代码)

2025国赛数学建模竞赛B题完整参考论文 目录 一、 问题重述 1.1 问题背景 1.2 问题回顾与分析 二、 模型假设 三、 符号说明 四、 问题求解与分析 4.1数据预处理 4.2 问题1求解与分析 4.2.1 问题1分析 4.2.2 问题1建模与求解 4.2.3 问题1结果与分析 4.3 问题2求解与分…

OpenSSL 1.0.1e 下载解压和运行方法(小白适用 附安装包)​

openssl-1.0.1e.zip​ 是 OpenSSL 加密工具包的一个旧版本&#xff08;发布于 2013 年左右&#xff09;的 ​源代码压缩包&#xff0c;文件格式是 ZIP 压缩格式。 一、下载与解压 ​下载文件​ 假如你已经有了 openssl-1.0.1e.zip 这个压缩包&#xff0c;就跳过这步。 如果没有…

MapStruct详解

提到属性拷贝&#xff0c;首先想到的BeanUtils。 先简单的回忆下BeanUtils&#xff0c;处理Java Bean之间的属性拷贝&#xff1b;不过由于它是通过反射来拷贝属性&#xff0c;在数据量大一些的时候性能会降低&#xff1b; 且在安全方面也会比较弱&#xff1b; MapStruct是编译期…

8.FC平台模块梳理

文章目录8.FC平台模块梳理8.1. 内存复用技术特点应用价值8.2. 虚拟机启用策略8.3. NUMA8.4. HA高可用8.5. 故障和响应策略8.6. DRS 和 DPM8.7. IMC8.FC平台模块梳理 8.1. 内存复用 内存共享内存交换内存气泡 内存共享&#xff1a;多台虚拟机共享数据内容相同的内存页。内存交换…

贪心算法应用:DNA自组装问题详解

JAVA中的贪心算法应用&#xff1a;DNA自组装问题详解 1. DNA自组装问题概述 DNA自组装(DNA Self-Assembly)是分子计算和纳米技术中的一个重要问题&#xff0c;它利用DNA分子的互补配对特性&#xff0c;通过精心设计DNA序列&#xff0c;使其自发地组装成预定的纳米结构。在计算机…

数据湖如何打造统一存储与处理方案(结构化数据、半结构化数据和非结构化数据)

目录 1. 数据湖的“包容哲学”:为什么需要统一方案? 数据湖的核心诉求 案例:零售企业的痛点 2. 存储层设计:给数据找个舒适的家 分区与分层存储 选择存储格式 案例:Parquet的威力 云存储的选择 3. 元数据管理:给数据湖装上“导航仪” 元数据管理的核心组件 主流…

AUTOSAR进阶图解==>AUTOSAR_SWS_TTCANDriver

TTCAN驱动器详细规范 AUTOSAR TTCAN Driver Specification with Enhanced Visual Documentation目录 1. 概述2. TTCAN控制器状态机3. TTCAN模块架构4. TTCAN时间触发操作序列5. TTCAN错误处理流程6. 总结 1. 概述 TTCAN&#xff08;Time-Triggered CAN&#xff09;驱动器是AU…

equals 定义不一致导致list contains错误

错误代码如下&#xff1a;for (int i0;i< rows.size();i) {Row r rows.get(i);if (r.equals(row)) {assertTrue(rows.contains(row));return;}}cassertTrue(rows.contains(row));返回了false&#xff0c;看起来很奇怪&#xff0c;此时equals 定义如下&#xff1a;public bo…

【Python基础】 20 Rust 与 Python 循环语句完整对比笔记

一、基本循环结构对比 Rust 循环类型 // 1. loop - 无限循环 let mut count 0; loop {count 1;if count > 5 {break;} }// 2. while - 条件循环 let mut number 3; while number ! 0 {println!("{}!", number);number - 1; }// 3. for - 迭代循环 for i in 0..…