(树) 剑指 Offer 28. 对称的二叉树 ——【Leetcode每日一题】

news2024/11/19 7:22:03

❓ 剑指 Offer 28. 对称的二叉树

难度:简单

请实现一个函数,用来判断一棵二叉树是不是对称的。如果一棵二叉树和它的镜像一样,那么它是对称的。

例如,二叉树 [1,2,2,3,4,4,3] 是对称的。

    1

   / \

  2   2

 / \ / \

3  4 4  3

但是下面这个 [1,2,2,null,3,null,3] 则不是镜像对称的:

    1

   / \

  2   2

   \   \

   3    3

示例 1:

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

示例 2:

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

限制

  • 0 <= 节点个数 <= 1000

注意:本题与 101. 对称二叉树 相同。

💡思路:

法一:递归

如果一个树的左子树与右子树镜像对称,那么这个树是对称的:

  • 每次检查当前 root1root2 节点的值是否 相等;
  • 如果 相等 再判断左右子树是否对称:
    • root1左子树 对应 root2右子树
    • root1右子树 对应 root2左子树
    • 同时成立时返回 true

法二:迭代

方法一 中我们用 递归 的方法实现了对称性的判断,那么如何用迭代的方法实现呢?

  • 要引入一个 队列 q,这是把递归程序改写成迭代程序的常用方法。

如果 root 不为空,将左右子树根节点分别加入队列:

  • 只要队列不为空,每次从队列中提取两个结点并比较它们的值(队列中每两个连续的结点应该是相等的,而且它们的子树互为镜像);
  • 然后将两个结点的左右子树按相反的顺序插入队列中;
    • 插入 temp1 的左子树后,紧接着插入 temp2 的右子树的根节点;
    • 然后再插入 temp1 的右子树后,紧接着插入 temp2 的左子树的根节点;
  • 当队列为空时,或者我们检测到树不对称(即从队列中取出两个不相等的连续结点)时,该算法结束。

🍁代码:(C++、Java)

法一:递归
C++

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
private:
    bool isSymTree(TreeNode* root1, TreeNode* root2){
        if(root1 == nullptr && root2 == nullptr) return true;
        if(root1 == nullptr || root2 == nullptr || (root1->val != root2->val)) return false;
        return isSymTree(root1->left, root2->right) && isSymTree(root1->right, root2->left);
    }
public:
    bool isSymmetric(TreeNode* root) {
        if(root == nullptr) return true;
        return isSymTree(root->left, root->right);
    }
};

Java

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    private boolean isSymTree(TreeNode root1, TreeNode root2){
        if(root1 == null && root2 == null) return true;
        if(root1 == null || root2 == null || (root1.val != root2.val)) return false;
        return isSymTree(root1.left, root2.right) && isSymTree(root1.right, root2.left);
    }
    public boolean isSymmetric(TreeNode root) {
        if(root == null) return true;
        return isSymTree(root.left, root.right);
    } 
}

法二:迭代
C++

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    bool isSymmetric(TreeNode* root) {
        if(root == nullptr) return true;
        queue<TreeNode*> q;
        q.push(root->left);
        q.push(root->right);
        while(!q.empty()){
            TreeNode* temp1 = q.front();
            q.pop();
            TreeNode* temp2 = q.front();
            q.pop();
            if(temp1 == nullptr && temp2 == nullptr) continue;
            if(temp1 == nullptr || temp2 == nullptr || (temp1->val != temp2->val)) return false;
            q.push(temp1->left);
            q.push(temp2->right);
            q.push(temp1->right);
            q.push(temp2->left);
        }
        return true;
    }
};

Java

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public boolean isSymmetric(TreeNode root) {
        if(root == null) return true;
        Queue<TreeNode> q = new LinkedList<TreeNode>();
        q.offer(root.left);
        q.offer(root.right);
        while(!q.isEmpty()){
            TreeNode temp1 = q.poll();
            TreeNode temp2 = q.poll();
            if(temp1 == null && temp2 == null) continue;
            if(temp1 == null || temp2 == null || (temp1.val != temp2.val)) return false;
            q.offer(temp1.left);
            q.offer(temp2.right);
            q.offer(temp1.right);
            q.offer(temp2.left);
        }
        return true;
    } 
}

🚀 运行结果:

在这里插入图片描述

🕔 复杂度分析:

  • 时间复杂度 O ( n ) O(n) O(n),其中 nroot 的节点数,遍历了这棵树。
  • 空间复杂度 O ( n ) O(n) O(n)法一 的空间复杂度和递归使用的栈空间有关,这里递归层数不超过 n ; 法二 需要用一个队列来维护节点,每个节点最多进队一次,出队一次,队列中最多不会超过 n 个点。

题目来源:力扣。

放弃一件事很容易,每天能坚持一件事一定很酷,一起每日一题吧!
关注我LeetCode主页 / CSDN—力扣专栏,每日更新!

注: 如有不足,欢迎指正!

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

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

相关文章

在Python中导入gurobipy模块显示ModuleNotFoundError: No module named ‘gurobipy‘的解决办法

笔者在学习用pythonAnacondagurobi求解优化问题时遇到了这个问题&#xff0c;看了很多帖子的方法都没有解决&#xff0c;所以这里分享一下自己的解决办法。 首先找到自己用的Anaconda3所在位置&#xff0c;这里不再赘述。 下拉文件夹找到envs&#xff0c;双击PythonProject&…

【雕爷学编程】MicroPython动手做(18)——掌控板之声光传感器

知识点&#xff1a;什么是掌控板&#xff1f; 掌控板是一块普及STEAM创客教育、人工智能教育、机器人编程教育的开源智能硬件。它集成ESP-32高性能双核芯片&#xff0c;支持WiFi和蓝牙双模通信&#xff0c;可作为物联网节点&#xff0c;实现物联网应用。同时掌控板上集成了OLED…

深入探索Linux文件系统与挂载点:掌握分区、挂载技巧

Linux 文件系统就是在 Linux 操作系统里咱们用来组织和管理文件的工具。它规定了文件和文件夹的结构&#xff0c;还确定了它们在存储设备上的储存方式。大致上来说&#xff0c;Linux 有很多种文件系统&#xff0c;比如 ext4、XFS、Btrfs 等。 挂载点其实就是把一个文件系统与 …

VS Code环境配置问题

VS Code 环境配置问题 文章目录 VS Code 环境配置问题配置 C问题解决不乱码只显示结果避免闪退&#xff0c;中文乱码 配置 Java下载 JDKJDK 环境配置安装插件 配置 C 跟着官网教程&#xff08;英文版&#xff09;和其他博客配置了一遍&#xff0c;却遇到了很多小问题&#xff…

2023“Java 基础 - 中级 - 高级”面试集结,已奉上我的膝盖

Java 基础&#xff08;对象线程字符接口变量异常方法&#xff09; 面向对象和面向过程的区别&#xff1f; Java 语言有哪些特点&#xff1f; 关于 JVM JDK 和 JRE 最详细通俗的解答 Oracle JDK 和 OpenJDK 的对比 Java 和 C的区别&#xff1f; 什么是 Java 程序的主类&…

Metabase 远程代码执行(CVE-2023-38646)

漏洞描述 Metabase是一款开源数据分析及可视化工具。它可允许用户连接至各种不同类型数据源,未经身份认证的攻击者可利用本漏洞在服务器上以运行 Metabase服务器的权限进行任意命令执行。 免责声明 技术文章仅供参考,任何个人和组织使用网络应当遵守宪法法律,遵守公共秩…

第133页的gtk+编程例子——计算器应用改写网上的例子用gtk4编译

第133页的gtk编程例子——计算器应用改写网上的例子用gtk4编译 来源&#xff1a;《GTK的计算器》 https://blog.csdn.net/zhouzhouzf/article/details/17097999 例子程序是在gtk2.0编译的&#xff0c;之前修改许多地方才能在gtk3.0编译通过&#xff0c;如今再修改能在gtk4编译…

进阶高级测试专项,Pytest自动化测试框架总结(三)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 1、pytest前置条件…

谈一谈缓存穿透,击穿,雪崩

缓存穿透 缓存穿透是指在使用缓存系统时&#xff0c;频繁查询一个不存在于缓存中的数据&#xff0c;导致这个查询每次都要通过缓存层去查询数据源&#xff0c;无法从缓存中获得结果。这种情况下&#xff0c;大量的请求会直接穿透缓存层&#xff0c;直接访问数据源&#xff0c;…

04 http连接处理(上)

基础知识&#xff1a;epoll、http报文格式、状态码和有限状态机 代码&#xff1a;对服务端处理http请求的全部流程进行简要介绍&#xff0c;然后结合代码对http类及请求接收进行详细分析。 epoll epoll_create函数 #include <sys/epoll.h> int epoll_create(int size)…

深度学习实践——模型部署优化实践

系列实验 深度学习实践——卷积神经网络实践&#xff1a;裂缝识别 深度学习实践——循环神经网络实践 深度学习实践——模型部署优化实践 深度学习实践——模型推理优化练习 源码&#xff1a; 1. 对应的github地址 https://github.com/Asionm/streamlit_demo 2. 对应的gitee地…

Session、Cookie 与 Application

目录 简介cookiecookie生命周期 sessionsession生命周期 application 简介 cookie、seesion、application三个都会缓存我们用户状态的数据&#xff0c;使得我们在浏览器访问网站时可以更快速的获取到信息。 主要原因在于HTTP协议是无状态的&#xff0c;我们每次访问服务器&…

软考05根据内存区域大小计算芯片数量

文章目录 前言一、原题二、解题思路1.计算内存区域的大小2.计算每个存储器芯片的容量3.计算芯片数量 总结 前言 从网上看题答案是有了&#xff0c;但是不知道具体的计算过程就很难受&#xff0c;不然下次还是不会&#xff0c;只能自己梳理了 一、原题 二、解题思路 1.计算内存…

ANR底层源码分析之Service篇

ANR底层源码分析之Service篇 一、前言二、Service-ANR原理2.1 Service启动ANR原理简述2.2 前台Service VS 后台Service的区别2.2.1 前台Service2.2.3 后台Service 2.3 Service启动ANR源码执行过程2.3.1 ActiveServices#bringUpServiceLocked2.3.2 ActiveServices#realStartServ…

数据安全

数据的备份与恢复 1. 数据备份技术 任何数据在长期使用过程中&#xff0c;都存在一定的安全隐患。由于认为操作失误或系统故障&#xff0c;例如认为错误、程序出错、计算机失效、灾难和偷窃&#xff0c;经常造成数据丢失&#xff0c;给个人和企业造成灾难性的影响。在这种情况…

LeetCode 刷题 数据结构 数组 27 移除元素

难度&#xff1a;简单 给你一个数组 nums 和一个值 val&#xff0c;你需要 原地 移除所有数值等于 val 的元素&#xff0c;并返回移除后数组的新长度。 不要使用额外的数组空间&#xff0c;你必须仅使用 O(1) 额外空间并 原地 修改输入数组。 元素的顺序可以改变。你不需要考虑…

SpringBoot自动装配介绍

SpringBoot是对Spring的一种扩展&#xff0c;其中比较重要的扩展功能就是自动装配&#xff1a;通过注解对常用的配置做默认配置&#xff0c;简化xml配置内容。本文会对Spring的自动配置的原理和部分源码进行解析&#xff0c;本文主要参考了Spring的官方文档。 自动装配的组件 …

西安科技大学:励志图存,自强不息

今天就让我带着大家一起来看“采矿冶金历史悠久&#xff0c;安全工程国重学科”的西安科技大学吧&#xff01; 一、高校概况 西安科技大学&#xff08;Xi’an University of Science and Technology&#xff09;&#xff0c;简称西科大、西安科大&#xff0c;位于陕西省西安市…

算法通关村第二关——指定区间反转的问题解析

题目类型 指定区间反转 题目描述 给你单链表的头指针 head 和两个整数left 和right &#xff0c;其中left < right 。请反转从位置left到位置right的链表节点&#xff0c;返回反转后的链表 示例 输入&#xff1a;head [1,2,3,4,5] , left 2 , right 4 输出&#xff1a;[…

「网络编程」传输层协议_ TCP协议学习_及原理深入理解(二 - 完结)[万字详解]

「前言」文章内容大致是传输层协议&#xff0c;TCP协议讲解的第二篇&#xff0c;续上篇TCP。 「归属专栏」网络编程 「主页链接」个人主页 「笔者」枫叶先生(fy) 目录 二、TCP协议2.9 TCP连接管理机制2.9.1 三次握手2.9.2 四次挥手2.9.3 演示查看TIME_WAIT和CLOSE_WAIT状态2.9.…