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

news2024/9/22 13:45:56

一、二叉树的层序遍历

题目:

给你二叉树的根节点 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) {
    // 边界情况处理:
    // 左子树不为空而右子树为空,或者左子树为空而右子树不为空,二叉树不对称,返回 false
    if (left != null && right == null)
        return false;
    if (left == null && right != null)
        return false;
    
    // 左右子树都为空,认为对称,返回 true
    if (left == null && right == null)
        return true;
    
    // 比较当前节点值是否相等,若不相等,二叉树不对称,返回 false
    if (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.coloradmin.cn/o/1939952.html

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

相关文章

使用 PVE 自签 CA 证书签发新证书

前言 PVE 安装时会自动创建一个有效期 10 年的 CA 证书, 我们可以利用这个 CA 证书给虚拟机中的 Web 应用签发新的 TLS 证书用于提供 HTTPS 服务. 下面以 PVE 虚拟机中通过 Docker 跑的一个 雷池 应用为例进行演示. PVE 证书位置 官方文档: https://pve.proxmox.com/wiki/Pr…

【BUG】已解决:TypeError: Descriptors cannot not be created directly.

已解决&#xff1a;TypeError: Descriptors cannot not be created directly. 目录 已解决&#xff1a;TypeError: Descriptors cannot not be created directly. 【常见模块错误】 【错误原因】 【解决方案】 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来…

STM32项目分享:智能宠物喂食系统

目录 一、前言 二、项目简介 1.功能详解 2.主要器件 三、原理图设计 四、PCB硬件设计 1.PCB图 五、程序设计 六、实验效果 七、资料内容 项目分享 一、前言 项目成品图片&#xff1a; 哔哩哔哩视频链接&#xff1a; https://www.bilibili.com/video/BV1zy411z7…

知名在线市场 Etsy 允许在其平台上销售 AI 艺术品,但有条件限制|TodayAI

近日&#xff0c;以手工和复古商品著称的在线市场 Etsy 宣布&#xff0c;将允许在其平台上销售 AI 生成的艺术品。这一举措引发了广泛关注和争议。尽管 Etsy 正在接受 AI 艺术的潮流&#xff0c;但平台对这一类商品的销售设置了一些限制。 根据 Etsy 新发布的政策&#xff0c;…

C#开发:PowerDesigner建表和Navicat导入数据

一、打开Powerdesigner&#xff0c;新建一个模型&#xff0c;点击ok 二、用工具面板拖拽出一个数据表 &#xff08;如果没有工具面板&#xff0c;请在如下操作中开启&#xff09; 三、双击刚刚的拖拽出来的表&#xff0c;设计表的字段&#xff0c;可以添加注释说明 【备注】…

开源智能助手平台Dify是什么?

1.背景 对于国内小公司&#xff0c;怎样通过Ai 将内部流程、产品重新做一次&#xff0c;从而提高人效、给客户带来价值&#xff0c;这是老板们在考虑的问题 &#xff1f; 当前市面上的你大模型例如&#xff1a;通义千问、文心一言、kimi、智谱清言、盘古 等&#xff0c;底层能…

【LeetCode】填充每个节点的下一个右侧节点指针 II

目录 一、题目二、解法完整代码 一、题目 给定一个二叉树&#xff1a; struct Node { int val; Node *left; Node *right; Node *next; } 填充它的每个 next 指针&#xff0c;让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点&#xff0c;则将 next 指针设置为 NUL…

【栈和队列】算法题 ---- 力扣

通过前面栈和队列的学习&#xff0c;现在来看这些算法题目 一、有效的括号 本题让判断括号是否有效 第一眼看可能没一点思路&#xff0c;但仔细分析一下&#xff1b; 我们学习过栈数据结构&#xff0c;知道栈先进后出的原则&#xff0c;那我们就可以使用啊&#xff1b;把题目的…

认识和安装R的扩展包,什么是模糊搜索安装,工作目录和空间的区别与设置

R语言以其强大的功能和灵活的扩展性,成为了无数数据分析师和研究者的首选工具。R的丰富功能和海量扩展包直接相关,但如何高效管理这些扩展包,进而充分发挥R的强大潜力?本文将为您揭示这些问题的答案。 一、R的扩展包 R的包(packages)是由R函数、数据和预编译代码组成的一…

PyQT6---环境搭建

1、虚拟环境搭建 创建虚拟环境 create -n pyqt6_39 python3.9 切换虚拟环境 conda activate pyqt6_39 2、安装pyqt6 安装pyqt6和pyqt6-tools pip install PyQt6 -i https://pypi.tuna.tsinghua.edu.cn/simplepip install pyqt6-tools -i https://pypi.tuna.tsinghua.edu.cn/…

关卡1-3:Git

关卡1-3&#xff1a;Git Git基础fork并拉取本次课程的源创建一个gitee自己的仓库 这个是internLM的3期训练营的通关笔记。 任务&#xff1a; 熟悉git熟悉使用git托管平台&#xff0c;常见有github、giteefork官方的训练营的教程项目&#xff0c;提交文件到自己的项目&#xf…

算法力扣刷题记录 五十六【501.二叉搜索树中的众数】

前言 二叉搜索树操作&#xff0c;继续。 记录 五十六【501.二叉搜索树中的众数】 一、题目阅读 给你一个含重复值的二叉搜索树&#xff08;BST&#xff09;的根节点 root &#xff0c;找出并返回 BST 中的所有 众数&#xff08;即&#xff0c;出现频率最高的元素&#xff09;…

基于机器学习的二手房价格分析与预测设计与实现

概述 随着西安房地产市场的不断发展和变化&#xff0c;对二手房价格的准确预测变得至关重要。本研究旨在利用机器学习技术对西安市二手房价格进行深入分析与预测&#xff0c;通过对原始数据进行数据预处理和特征提取&#xff0c;以构建有效的预测模型。通过数据分析和可视化&a…

IP数据报结构详解:从基础到进阶

目录 IP数据报的格式 IP数据报首部的固定部分 IP数据报首部的可变部分 实例分析&#xff1a;数据报的分片 生存时间&#xff08;TTL&#xff09;与协议 首部检验和 总结 在网络通信中&#xff0c;IP数据报是至关重要的基本单元。本文将带您深入了解IP数据报的格式及其各个…

Java | Leetcode Java题解之第264题丑数II

题目&#xff1a; 题解&#xff1a; class Solution {public int nthUglyNumber(int n) {int[] dp new int[n 1];dp[1] 1;int p2 1, p3 1, p5 1;for (int i 2; i < n; i) {int num2 dp[p2] * 2, num3 dp[p3] * 3, num5 dp[p5] * 5;dp[i] Math.min(Math.min(num2…

C语言顺序表插入删除 尾删 任意删除 任意插入 链表头插

各位少年&#xff0c;大家好我是小敖 &#xff0c;今天给大家分享 顺序表的头删 尾删&#xff0c;任意删除&#xff0c;任意插入&#xff0c;链表头插。接下来跟大家分享。 头插的操作 c void SLPushFront(SL*psl, SLDatatype x) {SLCheckCapacity(psl); int end psl->siz…

stm32平台为例的软件模拟时间,代替RTC调试

stm32平台为例的软件模拟时间&#xff0c;代替RTC调试 我们在开发项目的时候&#xff0c;如果用到RTC&#xff0c;如果真正等待RTC到达指定的时间&#xff0c;那调试时间就太长了。 比如每隔半个小时&#xff0c;存储一次数据&#xff0c;如果要观察10次存储的效果&#xff0…

nginx通过nginx_upstream_check_module实现后端健康检查

1、简介说明 nginx是常用的反向代理和负载均衡服务&#xff0c;具有强大并发能力、稳定性、丰富的功能集、低资源的消耗。 nginx自身是没有针对后端节点健康检查的&#xff0c;但是可以通过默认自带的ngx_http_proxy_module 模块和ngx_http_upstream_module模块中的相关指令来完…

LDR6020双盲插便携显示器应用

随着USB Type-C接口的普及&#xff0c;越来越多的手机和笔记本电脑都支持通过C接口输出视频。这个小巧而精密的接口&#xff0c;大有把传统的HDMI和DisplayPort接口取而代之的架势。特别是usb4的推出&#xff0c;更是为USB TYPE-C接口一统有线接口形态奠定了基础。 单USB-C接口…

电子电器架构 - SOA架构软件平台

电子电器架构 - SOA架构软件平台 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 屏蔽力是信息过载时代一个人的特殊竞争力,任何消耗你的人和事,多看一眼都是你的不对。非必要不费力证明自己,无…