算法日记day 16(二叉树的广度优先遍历|反转、对称二叉树)

一、二叉树的层序遍历

题目:

给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。

示例 1:

输入:root = [3,9,20,null,null,15,7]
输出:[[3],[9,20],[15,7]]

示例 2:

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

示例 3:

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

思路:

用队列来存储元素,变量size来存储每一层的元素个数,扫描队头元素,判断其是否有左右孩子,如果有,将其入队,同时该队头元素出队,记录在该层所封装的结果集中,同时size减一,当size值减为0时,说明该层所有元素均遍历完毕,返回结果集

代码:

// 结果列表,用于存储每一层的节点值列表
public List<List<Integer>> resList = new ArrayList<List<Integer>>();// 主方法,进行二叉树的层次遍历
public List<List<Integer>> levelOrder(TreeNode root) {// 调用辅助方法进行层次遍历test(root);// 返回结果列表return resList;
}// 辅助方法,实现二叉树的层次遍历
public void test(TreeNode root) {// 如果根节点为空,直接返回if (root == null)return;// 创建队列,用于存储待处理的节点Queue<TreeNode> queue = new LinkedList<>();queue.add(root); // 将根节点加入队列// 循环处理队列中的节点,直到队列为空while (!queue.isEmpty()) {// 用于存储当前层节点值的列表List<Integer> list = new LinkedList<>();int len = queue.size(); // 当前层节点的数量// 处理当前层的所有节点while (len > 0) {TreeNode tnode = queue.poll(); // 出队列,获取当前处理的节点list.add(tnode.val); // 将节点值加入当前层的列表// 将当前节点的左右子节点加入队列,用于下一层处理if (tnode.left != null)queue.add(tnode.left);if (tnode.right != null)queue.add(tnode.right);len--; // 当前层节点数减一}// 将当前层的节点值列表加入结果列表resList.add(list);}
}
  1. resList 定义和初始化

    • public List<List<Integer>> resList = new ArrayList<List<Integer>>();
    • 定义了一个成员变量 resList,用于存储二叉树的层次遍历结果。初始化为空的 ArrayList,用于存储每一层的节点值列表。
  2. levelOrder 方法

    • public List<List<Integer>> levelOrder(TreeNode root)
    • 主方法,调用 test 方法进行二叉树的层次遍历,并返回最终的层次遍历结果 resList
  3. test 方法

    • public void test(TreeNode root)
    • 辅助方法,实现二叉树的层次遍历。
    • 使用队列 queue 进行广度优先搜索(BFS):
      • 首先将根节点加入队列。
      • 每次处理队列中的一个节点,将其值加入当前层的 list 中,并将其左右子节点(如果存在)加入队列。
      • 每处理完一层的所有节点后,将当前层的节点值列表 list 加入 resList 中。

二、翻转二叉树

题目:

给你一棵二叉树的根节点 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 = []
输出:[]

思路:

可以采用递归前序和后序遍历的方法,遍历一个结点的同时反转其左右子节点,接着往下一层移动,重复以上操作,直到遍历到的节点为空停止

代码:

//前序
public TreeNode invertTree(TreeNode root) {if (root == null)return root;swap(root); // 调用 swap 方法,交换当前节点的左右子节点  中invertTree(root.left); // 递归翻转左子树   左invertTree(root.right); // 递归翻转右子树   右return root; // 返回翻转后的根节点
}
public void swap(TreeNode root) {TreeNode temp = root.left;root.left = root.right;root.right = temp;
}

后序遍历方法类似,只需将顺序修改为左,右,中即可

用中序遍历的方法稍有不同,由于中序是左,中,右的顺序,当返回到根节点时左右子树交换顺序,此时应该继续遍历右子树,但是这时的右子树正好是刚刚交换完的左子树 ,因此实际上仅是交换了一次左子树,要想实现反转,必须再次进行左子树的交换操作即可,代码如下:

invertTree(root.left); // 递归翻转左子树   左
swap(root); // 调用 swap 方法,交换当前节点的左右子节点  中
invertTree(root.left); // 这时再次操作反转后的左子树   右

 

三、对称二叉树

题目:

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

示例 1:

输入:root = [1,2,2,3,4,4,3]
输出:true

示例 2:

输入:root = [1,2,2,null,3,null,3]
输出:false

思路:

采用后序遍历的方法,为什么要采用后序呢?由于后序遍历的顺序是左,右,中,而要判断二叉树是否对称就是要判断根节点的左右子树是否在翻转后可以重合,后序的遍历顺序正好可以判断左右子树,再在最后遍历根节点,具体方法是,先遍历根节点的左右子节点是否相同,再判断左子节点的左子节点是否与右子节点的右子节点相同,同理再判断左子节点的右子节点是否和右子节点的左子节点相同,重复上述操作,直到为空

代码:

// 判断给定的二叉树是否对称的方法
public boolean isSymmetric(TreeNode root) {// 调用 compare 方法,比较根节点的左右子树是否对称return compare(root.left, root.right);
}// 递归比较两棵树是否对称的方法
public boolean compare(TreeNode left, TreeNode right) {// 边界情况处理:// 左子树不为空而右子树为空,或者左子树为空而右子树不为空,二叉树不对称,返回 falseif (left != null && right == null)return false;if (left == null && right != null)return false;// 左右子树都为空,认为对称,返回 trueif (left == null && right == null)return true;// 比较当前节点值是否相等,若不相等,二叉树不对称,返回 falseif (left.val != right.val)return false;// 递归比较左子树的左节点与右子树的右节点,外侧比较boolean Outcompare = compare(left.left, right.right);// 递归比较左子树的右节点与右子树的左节点,内侧比较boolean Intcompare = compare(left.right, right.left);// 返回外侧比较和内侧比较的与运算结果,确定整棵树是否对称return Outcompare && Intcompare;
}
  • 首先处理边界情况:
    • 如果 left 不为 null 而 right 为 null,或者 left 为 null 而 right 不为 null,则二叉树不对称,返回 false
    • 如果 left 和 right 都为 null,则认为是对称的,返回 true
  • 然后比较当前节点的值 left.val 和 right.val 是否相等,如果不相等,则二叉树不对称,返回 false
  • 如果当前节点值相等,继续递归比较 left 的左子节点 left.left 和 right 的右子节点 right.right 是否对称(外侧比较)。
  • 同时递归比较 left 的右子节点 left.right 和 right 的左子节点 right.left 是否对称(内侧比较)。
  • 最终返回外侧比较结果 Outcompare 和内侧比较结果 Intcompare 的与运算结果,即判断整棵树是否对称。

相关资料:

https://www.programmercarl.com/0101.%E5%AF%B9%E7%A7%B0%E4%BA%8C%E5%8F%89%E6%A0%91.html

今天的学习就到这里了! 

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

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

相关文章

SQUID - 形状条件下的基于分子片段的3D分子生成等变模型 评测

SQUID 是一个形状条件下基于片段的3D分子生成模型&#xff0c;给一个3D参考分子&#xff0c;SQUID 可以根据参考分子的形状&#xff0c;基于片段库&#xff0c;生成与参考分子形状非常相似的分子。 SQUID 模型来自于 ICLR 2023 文章&#xff08;2022年10月6日提交&#xff09;&…

vue+watermark-dom实现页面水印效果

前言 页面水印大家应该都不陌生&#xff0c;它可以用于验证数字媒体的来源和完整性&#xff0c;还可以用于版权保护和信息识别&#xff0c;这些信息可以在不影响媒体质量的情况下嵌入&#xff0c;‌并在需要时进行提取。‌本文将通过 vue 结合 watermark-dom 库&#xff0c;教大…

OpenCV 像素操作—证件照换底色详细原理 C++纯手写实现

文章目录 总体步骤1.RGB转HSV2.找出要换的底色3.取反&#xff0c;黑白颠倒4.将原图像的非背景部分复制到新背景上 完整代码1.C纯手写版2.官方API版本 总体步骤 1.RGB转HSV 为什么一定要转为HSV 颜色空间&#xff1f; 将图像从BGR颜色空间转换为HSV颜色空间是因为HSV颜色空间更…

nginx基本原理

进程模型 当nginx启动之后&#xff0c;会有一个master进程和多个worker进程。默认是一个worker进程。 master进程的作用&#xff1a;接收来自外界信号&#xff0c;向各worker进程发送信号&#xff0c;监控worker进程的运行状态&#xff0c;当worker进程在异常情况下退出后&am…

C#实现数据采集系统-实现功能介绍

系统介绍 我们这里主要使用C#( .Net 6)来实现一个数据采集系统&#xff0c;从0到1搭建数据采集系统&#xff0c;从系统分析&#xff0c;功能拆解&#xff0c;到一一实现 数据采集 数据采集是企业信息化和数字化转型过程中的关键环节&#xff0c;它涉及到从生产设备、传感器…

jupyter_contrib_nbextensions安装失败问题

目录 1.文件路径长度问题 2.jupyter不出现Nbextensions选项 1.文件路径长度问题 问题&#xff1a; could not create build\bdist.win-amd64\wheel\.\jupyter_contrib_nbextensions\nbextensions\contrib_nbextensions_help_item\contrib_nbextensions_help_item.yaml: No su…

【艺术向】【素描创作记录】《如何为你的红颜知己创作一幅画像(之二)》

写在前面 之前分析过类似的创作过程&#xff0c;见博客【艺术向】【素描创作记录】《如何为你的红颜知己创作一幅画像》 本人业余时间修习素描多年&#xff0c;在此撰文记录《如何为你的红颜知己创作一幅画像&#xff08;之二&#xff09;》&#xff0c;博得对方好感&#xff…

C++常见问题

一、C入门基础 1.1、函数重载 函数重载允许在同一作用域内定义多个同名函数&#xff0c;只要这个函数的参数列表&#xff08;即参数的数量&#xff0c;类型或者顺序不同&#xff09; 如何支持&#xff1a;程序经过编译后&#xff0c;编译器会对程序中的函数按一定规则进行重…

设计模式-Git-其他

目录 设计模式&#xff1f; 创建型模式 单例模式&#xff1f; 啥情况需要单例模式 实现单例模式的关键点&#xff1f; 常见的单例模式实现&#xff1f; 01、饿汉式如何实现单例&#xff1f; 02、懒汉式如何实现单例&#xff1f; 03、双重检查锁定如何实现单例&#xff…

封装MAVSDK为JAR包并导出给其它Android工程用完整示例

效果: 未解锁状态 已执行解锁指令 已执行起飞指令 飞行中 已执行降落指令 已执行返航指令 实现步骤: 1.准备PX4容器并启动:

ip地址是电脑还是网线决定的

在数字化时代的浪潮中&#xff0c;网络已经成为了我们日常生活和工作不可或缺的一部分。当我们谈论网络时&#xff0c;IP地址无疑是一个核心的概念。然而&#xff0c;关于IP地址的分配和决定因素&#xff0c;很多人可能存在误解。有些人认为IP地址是由电脑决定的&#xff0c;而…

springboot nacos的各种注解、手动操作监听配置变化(监听指定DataId/监听任何变化)

文章目录 springboot nacos监听配置变化&#xff08;监听指定DataId/监听任何变化&#xff09;监听任何配置变化Nacos注解NacosConfigurationPropertiesNacosValueNacosConfigListenerNacosInjectedNacosConfigServiceNacosNamingService springboot nacos监听配置变化&#xf…

QT--事件(丰富操作,高级功能)

一、事件 1.事件与信号的区别 事件来自外部&#xff0c;是随机发生的。信号来自内部&#xff0c;是主动发生的。有点像外中断和内中断的区别。事件&#xff1a;适用于处理系统级别的输入和状态变化&#xff0c;种类繁多&#xff0c;能够应对复杂的交互需求。信号/槽&#xff…

中国 X86 CPU 技术源自何方

注&#xff1a; 原文发布于 2017 年&#xff0c;两篇合二为一。未与作者沟通&#xff0c;侵权&#xff0c;立删。 导语&#xff1a; Intel 对 X86 的授权有着极为严格的限制&#xff0c;那么上海兆芯的 X86 芯片技术到底从何而来&#xff1f;ZX-C 目前的短板在哪里&#xff1f;…

pytorch 46 将ASpanFormer模型导出onnx运行

ASpanFormer是一个2022年8月份发布的算法,其主要步骤与LoFTR模型类似,因此无法导出为onnx模型。根据ASpanFormer论文中的数据与效果图,可以确定AsPanFormer是可以作为一个比SP+SG更为有效的方案,其在标准数据集上的效果优于SP+SG,在速度上远超SP+SG,与LoFTR接近;在预测点…

【深度学习入门项目】多层感知器(MLP)实现手写数字识别

多层感知器&#xff08;MLP&#xff09;实现手写数字识别 导入必要的包获得软件包的版本信息 下载并可视化数据查看一个batch的数据查看图片细节信息设置随机种子 定义模型架构Build model_1Build model_2 Train the Network (30 marks)Train model_1Train model_1Visualize th…

AI+X活动开放报名!Datawhale来南京了

Datawhale线下 主办方&#xff1a;讯飞开放平台、Datawhale、GDG南京 AIX 主题活动今年将走进 10 个城市&#xff0c;100 所高校&#xff0c;目前已经走进32所高校&#xff0c;以及北京、深圳、上海、杭州、武汉五个城市&#xff0c;南京是第六个城市&#xff0c;时间7月27号。…

IP-Trunk简介

定义 IP-Trunk是将多个链路层协议为HDLC的POS接口捆绑到一起&#xff0c;形成一条逻辑上的数据链路&#xff0c;以提供更高的连接可靠性和更大的带宽&#xff0c;实现流量负载分担。 目的 POS是一种应用在城域网及广域网中的技术&#xff0c;利用SONET/SDH提供的高速传输通道…

html改写vue日志

本人最近学了vue&#xff0c;想着练手的方法就是改写之前在公司开发的小系统前端&#xff0c;将前端的AJAXJSThymeleaf改为axiosvue。 改写html 将<html>中的<head>和<body>结构移除&#xff0c;将css部分移入<style>&#xff0c; 重新定义了全局的&…

视频汇聚,GB28181,rtsp,rtmp,sip,webrtc,视频点播等多元异构视频融合,视频通话,视频会议交互方案

现在视频汇聚&#xff0c;视频融合和视频互动&#xff0c;是视频技术的应用方向&#xff0c;目前客户一般有很多视频的业务系统&#xff0c;如已有GB28181的监控&#xff08;GB现在是国内主流&#xff0c;大量开源接入和商用方案&#xff09;&#xff0c;rtsp设备&#xff0c;音…