LeetCode101. 对称二叉树

news2024/11/15 18:33:03

101. 对称二叉树

一、题目

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

示例 1:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ci09xkEi-1690521063844)(D:\A_WHJ\Computer Science\typora图片\symtree1.jpg)]

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

示例 2:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6Gs1nZYn-1690521063845)(D:\A_WHJ\Computer Science\typora图片\symtree2.jpg)]

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

提示:

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

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

二、题解

方法一:递归

算法思路(建议对照题干里的图片理解)

要判断一棵二叉树是否轴对称,我们可以使用递归的方法。轴对称意味着该二叉树左右两侧镜像对称,即左子树的左子节点和右子树的右子节点相等,并且左子树的右子节点和右子树的左子节点相等。

我们可以定义一个辅助函数 isMirror,该函数接受两个节点作为参数,然后递归地比较这两个节点及其子树是否镜像对称。如果这两个节点都为空,则它们是对称的;如果其中一个为空而另一个不为空,则它们不对称;如果两个节点都不为空,那么我们需要判断它们的值是否相等,并继续递归判断左右子树的对称性。

接下来,我们只需要调用 isMirror(root, root),其中 root 是二叉树的根节点,来判断整个二叉树是否轴对称。

具体实现

class Solution {
public:
    bool isSymmetric(TreeNode* root) {
        return isMirror(root, root);
    }
    
    bool isMirror(TreeNode* node1, TreeNode* node2) {
        if (node1 == nullptr && node2 == nullptr) {
            return true; // 两个空节点是对称的
        }
        
        if (node1 == nullptr || node2 == nullptr) {
            return false; // 一个空节点一个非空节点不对称
        }
        
        // 比较当前节点的值,并递归判断左右子树的对称性
        // 轴对称意味着左子树的左子节点和右子树的右子节点相等,并且左子树的右子节点和右子树的左子节点相等
        return (node1->val == node2->val) &&
               isMirror(node1->left, node2->right) &&
               isMirror(node1->right, node2->left);
    }
};

算法分析

  • 时间复杂度:对于每个节点,我们最多访问其两个子节点,因此时间复杂度是 O(N),其中 N 是节点的数量。
  • 空间复杂度:递归调用的栈空间取决于二叉树的高度,最坏情况下,树是一个链状结构,空间复杂度为 O(N)。在平均情况下,树的高度较小,空间复杂度较低。

总结

判断二叉树是否轴对称可以使用递归的方法。我们定义一个辅助函数 isMirror,该函数用于递归比较两个节点及其子树是否镜像对称。根据节点是否为空,以及节点值是否相等,我们可以判断节点是否对称。然后,我们只需要调用 isMirror(root, root) 来判断整个二叉树是否轴对称。这个算法的时间复杂度是 O(N),最坏空间复杂度是 O(N)。

方法二、迭代

算法思路

  1. 我们可以使用迭代的方法来判断对称性,使用一个队列(deque)来辅助我们逐层遍历二叉树节点。首先将根节点两次入队,因为在一开始的时候,我们需要比较的是根节点的左子树和右子树。

  2. 在每一次循环中,我们从队列中取出两个节点node1和node2,并进行比较:

    • 如果两个节点都为nullptr,说明当前层级上是对称的,继续下一次循环;
    • 如果其中一个节点为nullptr而另一个节点不为nullptr,说明当前层级上不对称,直接返回false;
    • 如果两个节点的值不相等,说明当前层级上不对称,直接返回false。
  3. 如果当前节点node1和node2的值相等,说明当前层级上是对称的,我们将node1的左子树和node2的右子树以及node1的右子树和node2的左子树按照相反的顺序入队,以便继续判断下一层级。

  4. 当队列为空时,说明二叉树的对称性已经判断完毕,没有发现不对称的部分,返回true。

具体实现

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    bool isSymmetric(TreeNode* root) {
        deque<TreeNode*> deq;
        if(root == nullptr) return true;
        deq.push_back(root);
        deq.push_back(root);
        while(!deq.empty()){
            TreeNode *node1 = deq.front();
            deq.pop_front();
            TreeNode *node2 = deq.front();
            deq.pop_front();
            if(node1 == nullptr && node2 == nullptr) continue;
            if(node1 == nullptr || node2 == nullptr) return false;
            if(node1->val != node2->val) return false;
            deq.push_back(node1->left);
            deq.push_back(node2->right);
            deq.push_back(node1->right);
            deq.push_back(node2->left);
        }
        return true;
    }
};

算法分析

  • 时间复杂度: 假设二叉树中有n个节点,每个节点都需要进出队列一次,所以时间复杂度为O(n)。
  • 空间复杂度: 使用了一个双端队列(deque)来辅助存储节点,最坏情况下可能存储n/2个节点,所以空间复杂度为O(n)。

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

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

相关文章

一百三十七、Hive——HQL运行报错(持续更新中)

一、timestamp字段与int字段相加 &#xff08;一&#xff09;场景 change_time字段是timestamp字段&#xff0c;代表一个红绿灯周期的开始时间&#xff08;先是绿灯、再是黄灯、最后红灯&#xff09;&#xff0c;而green是int字段&#xff0c;代表绿灯的秒数&#xff0c;现在…

Linux常用基础命令-------你想要的我都有❀

文章目录❀ ❀ls命令 ❀cd命令 ❀pwd命令 ❀date命令 ❀创建、删除文件和目录命令 ❀alias命令 ❀复制、移动、重命名、查看&#xff08;文件、目录&#xff09;命令 ❀find查找、wc统计命令 ❀vi/vim命令 1、打开文件 2、工作模式 vi与vim的四个模式 进入编辑模式…

Verilog语法学习——LV2_异步复位的串联T触发器

LV2_异步复位的串联T触发器 题目来源于牛客网 [牛客网在线编程_Verilog篇_Verilog快速入门 (nowcoder.com)](https://www.nowcoder.com/exam/oj?page1&tabVerilog篇&topicId301) 题目 题目描述&#xff1a; 用verilog实现两个串联的异步复位的T触发器的逻辑&#x…

MacOS本地安装Hadoop3

金翅大鹏盖世英&#xff0c;展翅金鹏盖世雄。 穿云燕子锡今鸽&#xff0c;踏雪无痕花云平。 ---------------- 本文密钥&#xff1a;338 ----------------- 本文描述了在macbook pro的macos上安装hadoop3的过程&#xff0c;也可以作为在任何类linux平台上安装hadoop3借鉴。 …

传染病模型

title: 传染病模型 date: 2023-7-24 10:55:00 updated: 2023-7-24 10:55:00 tags: 算法数学建模传染病模型matlab categories: 数学建模 传染病模型中的符号表示 SI模型&#xff08;艾滋传染模型&#xff09; %% 直接求微分方程的解析解 dsolve(Dx1 -0.1 * x1 * x2 / 1000, D…

微服务契约测试框架Pact-Python实战

Pact是一个契约测试框架&#xff0c;有多种语言实现&#xff0c;本文以基于pact-python探究契约测试到底是什么&#xff1f;以及如何实现 官网&#xff1a;自述文件 |契约文档 (pact.io) 契约测试步骤 1、为消费者写一个单元测试&#xff0c;让它通过&#xff0c;并生成契约…

阿里Java开发手册~集合处理

1. 【强制】关于 hashCode 和 equals 的处理&#xff0c;遵循如下规则&#xff1a; 1 &#xff09; 只要重写 equals &#xff0c;就必须重写 hashCode 。 2 &#xff09; 因为 Set 存储的是不重复的对象&#xff0c;依据 hashCode 和 equals 进行判断&#xff…

MySQL之深入InnoDB存储引擎——物理文件

文章目录 一、参数文件二、日志文件三、表结构定义文件四、InnoDB 存储引擎文件1、表空间文件2、重做日志文件 一、参数文件 当 MySQL 实例启动时&#xff0c;数据库会先去读一个配置参数文件&#xff0c;用来寻找数据库的各种文件所在位置以及指定某些初始化参数。在默认情况…

vue启动失败问题

解决办法情况1&#xff1a;确认自己是否进入了vuedemo项目的目录。 解决办法情况2&#xff1a;目录进入正确npm start错误&#xff0c;这时可以进入自己电脑的项目文件中去删除node_modules和package-lock.json&#xff0c;然后回到控制台npm i或npm install安装依赖&#xff0…

SAP ABAP 自定义表数据导入

一:效果展示&#xff1a; 读取 Excel 数据到 SAP 数据库表。 二&#xff1a;源码&#xff1a; *&---------------------------------------------------------------------* *& Report ZTEST_DRW02 *&----------------------------------------------------------…

Unity游戏源码分享-2.5D塔防类游戏

Unity游戏源码分享-2.5D塔防类游戏 项目地址&#xff1a; https://download.csdn.net/download/Highning0007/88118947

《Federated Unlearning via Active Forgetting》论文精读

文章目录 1、概述2、方法实验主要贡献框架概述 3、实验结果比较方法实验结果忘却完整性忘却效率模型实用性 4、总结 原文链接&#xff1a; Federated Unlearning via Active Forgetting 1、概述 对机器学习模型隐私的⽇益关注催化了对机器学习的探索&#xff0c;即消除训练数…

【Spring】什么是Bean的生命周期及作用域,什么是Spring的执行流程?

博主简介&#xff1a;想进大厂的打工人博主主页&#xff1a;xyk:所属专栏: JavaEE进阶 在前面的播客中讲解了如何从Spring中存取Bean对象&#xff0c;那么本篇我们来讲解Bean对象的生命周期是什么&#xff0c;Bean对象的6种作用域分别是什么&#xff0c;都有哪些区别&#xff…

WebDAV之π-Disk派盘 + 静读天下

静读天下 支持WebDAV方式连接π-Disk派盘。 静读天下是一款备受千万Android用户好评的阅读工具,如果你享受本地阅读带来的宁静与踏实,同时对阅读器又有着苛刻要求,符合设计简洁、高效易用、功能强大且稳定,那么不妨试试这款app。静读天下支持txt、html、epub、umd、fb2、…

Python数据分析实战-利用limit 与 offset进行数据库数据批量查询与处理(附源码和实现效果)

实现功能 利用limit 与 offset进行数据库数据批量查询与处理 实现代码 def query_batch(self,engine,batch_step,end,sql):session make_session(engine)cursor session.execute(sql.format(batch_step, end))fields cursor._metadata.keysdf pd.DataFrame([dict(zip(fi…

LeetCode-116-填充每个节点的下一个右侧节点指针

一&#xff1a;题目描述&#xff1a; 给定一个 完美二叉树 &#xff0c;其所有叶子节点都在同一层&#xff0c;每个父节点都有两个子节点。二叉树定义如下&#xff1a; struct Node {int val;Node *left;Node *right;Node *next; }填充它的每个 next 指针&#xff0c;让这个指…

Flutter 的线程模型和异步原理

本文字数&#xff1a;&#xff1a;36130字 预计阅读时间&#xff1a;91分钟 在Android应用中&#xff0c; 用户时常会遇到界面卡顿的情况&#xff0c;非常影响用户的体验。作为Android开发肯定都知道&#xff1a;应用在主线程里做了大量的耗时操作(例如文件读写&#xff0c; 数…

新一代网络安全防护体系的五个关键特征

目前&#xff0c;网络安全技术正面临着一个转折点&#xff0c;基于边界的安全防护理论存在缺陷&#xff0c;基于规则的威胁判别机制不再有效&#xff0c;围绕传统技术构建的安全工程也不再适用。新一代安全建设不能再像修“城墙”一样&#xff0c;专注于外部网络攻击和已知威胁…

C++:类和对象(中)---默认成员函数---运算符重载---const的含义

文章目录 默认成员函数构造函数析构函数拷贝构造函数运算符重载赋值运算符重载const的含义取地址及const取地址操作符重载 默认成员函数 首先要理解什么是默认成员函数&#xff1a;类在什么都不写的时&#xff0c;编译器会生成六个默认成员函数 用户没有显式实现&#xff0c;但…

谁能讲清楚Spark之小白入门

在这我假设大家都是小白&#xff0c;那么Spark是什么&#xff1f;你为什么搜索它&#xff1f;思考一下。 首先&#xff0c;Spark是大数据处理框架的一种&#xff0c;那么什么是大数据处理框架&#xff1f;什么是大数据&#xff1f;字面意思懂得都懂。&#xff08;如果不懂去百度…