二叉树题目:对称二叉树

news2024/11/25 10:32:08

文章目录

  • 题目
    • 标题和出处
    • 难度
    • 题目描述
      • 要求
      • 示例
      • 数据范围
      • 进阶
  • 解法一
    • 思路和算法
    • 代码
    • 复杂度分析
  • 解法二
    • 思路和算法
    • 代码
    • 复杂度分析

题目

标题和出处

标题:对称二叉树

出处:101. 对称二叉树

难度

3 级

题目描述

要求

给你一个二叉树的根结点 root \texttt{root} root,检查它是否轴对称。

示例

示例 1:

示例 1

输入: root   =   [1,2,2,3,4,4,3] \texttt{root = [1,2,2,3,4,4,3]} root = [1,2,2,3,4,4,3]
输出: true \texttt{true} true

示例 2:

示例 2

输入: root   =   [1,2,2,null,3,null,3] \texttt{root = [1,2,2,null,3,null,3]} root = [1,2,2,null,3,null,3]
输出: false \texttt{false} false

数据范围

  • 树中结点数目在范围 [1,   1000] \texttt{[1, 1000]} [1, 1000]
  • -100 ≤ Node.val ≤ 100 \texttt{-100} \le \texttt{Node.val} \le \texttt{100} -100Node.val100

进阶

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

解法一

思路和算法

如果二叉树的左子树和右子树对称,则二叉树是对称二叉树。对称二叉树的左子树和右子树的结构和结点值满足左右翻转。

深度优先搜索的做法是,首先判断根结点的左子结点和右子结点是否存在和是否符合对称二叉树的要求,如果左子结点和右子结点存在且符合对称二叉树的要求,则继续对左子树和右子树判断。

由于二叉树的结构具有递归性,因此可以使用递归实现深度优先搜索。

p p p q q q 分别表示根结点的左子结点和右子结点。如果 p p p q q q 都为空,则原始二叉树是对称二叉树。如果 p p p q q q 只有一个为空,则原始二叉树的结构不符合对称二叉树的要求,因此原始二叉树不是对称二叉树。这两种情况是递归的终止条件。

对于其余情况,首先判断 p p p q q q 的结点值是否相同,然后执行递归。

  1. 如果 p p p q q q 的结点值不同,则原始二叉树不是对称二叉树。

  2. 如果 p p p q q q 的结点值相同,则只有当 p p p 的左子树和 q q q 的右子树对称且 p p p 的右子树和 q q q 的左子树对称时,原始二叉树才是对称二叉树。对 p p p q q q 的左右子树执行递归,判断原始二叉树是否为对称二叉树。

代码

class Solution {
    public boolean isSymmetric(TreeNode root) {
        return areSymmetric(root.left, root.right);
    }

    public boolean areSymmetric(TreeNode p, TreeNode q) {
        if (p == null && q == null) {
            return true;
        }
        if (p == null || q == null) {
            return false;
        }
        return p.val == q.val && areSymmetric(p.left, q.right) && areSymmetric(p.right, q.left);
    }
}

复杂度分析

  • 时间复杂度: O ( n ) O(n) O(n),其中 n n n 是二叉树的结点数。每个结点都被访问一次。

  • 空间复杂度: O ( n ) O(n) O(n),其中 n n n 是二叉树的结点数。空间复杂度主要是递归调用的栈空间,取决于二叉树的高度,最坏情况下二叉树的高度是 O ( n ) O(n) O(n)

解法二

思路和算法

也可以使用广度优先搜索遍历二叉树,判断二叉树是否为对称二叉树。

由于需要判断二叉树的左半部分和右半部分是否对称,因此需要同时从两个相反的方向遍历二叉树。使用两个队列分别存储两个方向遍历二叉树访问的结点。初始时将两个二叉树的根结点分别入两个队列,遍历过程中,每次从两个队列分别将一个结点出队列,这两个出队列的结点一定是两个二叉树中对称位置的两个结点,这两个结点分别称为结点一和结点二,执行如下操作。

  1. 如果两个结点值不同,则两个二叉树的对称位置处的两个结点值不同,因此二叉树不是对称二叉树。

  2. 如果两个结点值相同,则分别获得两个结点的左子结点和右子结点,如果结点一的左子结点和结点二的右子结点恰好有一个为空,或者结点一的右子结点和结点二的左子结点恰好有一个为空,则二叉树的结构不符合对称二叉树的要求,因此二叉树不是对称二叉树。

  3. 如果两个结点的左子结点和右子结点的结构符合对称二叉树的要求,则将两个结点的非空子结点分别入相应的队列,如果两个结点的左子结点和右子结点都不为空,则结点一的左子结点和右子结点依次入第一个队列,结点二的右子结点和左子结点依次入第二个队列。

当队列为空时,遍历结束,如果在任意位置,二叉树的结构和结点值都符合对称二叉树的要求,则二叉树是对称二叉树。

代码

class Solution {
    public boolean isSymmetric(TreeNode root) {
        Queue<TreeNode> queue1 = new ArrayDeque<TreeNode>();
        Queue<TreeNode> queue2 = new ArrayDeque<TreeNode>();
        queue1.offer(root);
        queue2.offer(root);
        while (!queue1.isEmpty()) {
            TreeNode node1 = queue1.poll();
            TreeNode node2 = queue2.poll();
            if (node1.val != node2.val) {
                return false;
            }
            TreeNode left1 = node1.left, right1 = node1.right, left2 = node2.left, right2 = node2.right;
            if (left1 == null ^ right2 == null) {
                return false;
            }
            if (right1 == null ^ left2 == null) {
                return false;
            }
            if (left1 != null) {
                queue1.offer(left1);
                queue2.offer(right2);
            }
            if (right1 != null) {
                queue1.offer(right1);
                queue2.offer(left2);
            }
        }
        return true;
    }
}

复杂度分析

  • 时间复杂度: O ( n ) O(n) O(n),其中 n n n 是二叉树的结点数。每个结点在两个方向各访问一次。

  • 空间复杂度: O ( n ) O(n) O(n),其中 n n n 是二叉树的结点数。空间复杂度主要是队列空间,每个队列内元素个数不超过 n n n

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

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

相关文章

Linux的编译器——gcc/g++(预处理、编译、汇编、链接)

文章目录 一.程序实现的两个环境二.gcc如何完成1.预处理2.编译3.汇编4.链接 三.动态库与静态库对比下二者生成的文件大小 四.gcc常用选项 前言&#xff1a; 本文主要认识与学习Linux环境下常用的编译器——gcc&#xff08;编译C代码&#xff09;/g&#xff08;编译C代码&#x…

ECharts社区 合集整理

1、PPChart 地址&#xff1a;http://ppchart.com/#/ 2、DataInsight 地址&#xff1a;http://chartlib.datains.cn/echarts 3、isqqw 地址&#xff1a;https://www.isqqw.com/ 4、makeapie 地址&#xff1a;https://www.makeapie.cn/echarts 5、Chart.Top 地址: http://chart.…

【二维属性+贪心+双指针】Wannafly 挑战赛15 A

Wannafly挑战赛15_ACM/NOI/CSP/CCPC/ICPC算法编程高难度练习赛_牛客竞赛OJ (nowcoder.com) 题意&#xff1a; 思路&#xff1a; 经典中的经典中的经典 还是一样双指针把可行解放入DS中&#xff0c;然后求最优解 值得注意的是&#xff0c;我们说的双指针的单调性&#xff0c…

SpringCloudAlibaba集成RocketMQ实现分布式事务事例(一)

SpringCloudAlibaba集成RocketMQ实现分布式事务事例(一) 业务需求 用户请求订单微服务 order-service 接口删除订单(退货),删除订单时需要调用 account-service的方法给账户增加余额,一个典型的分布式事务问题。 代码实现 事务消息有三种状态: TransactionStatus.Commi…

第162天:应急响应-网站入侵篡改指南Webshell内存马查杀漏洞排查时间分析

知识点 #知识点 -网页篡改与后门攻击防范应对指南 主要需了解&#xff1a;异常特征&#xff0c;处置流程&#xff0c;分析报告等 主要需了解&#xff1a;日志存储&#xff0c;Webshell检测&#xff0c;分析思路等 掌握&#xff1a; 中间件日志存储&#xff0c;日志格式内容介绍…

操作系统复习大纲

目录 第一章 操作系统引论 1. 理解操作系统的目标 2. 理解 OS 的作用 3. 理解操作系统的功能 4. 深入理解多道、并发 OS 的含义 5. 掌握多道批处理 OS、分时 OS、实时 OS 的基本特性&#xff0c;掌握分时 OS 基本特点 和响应时间概念和公式 Tn q。 6. 了解 OS 设计目的 7. 理解…

【枚举倍数】找一找

A-找一找_Wannafly挑战赛9 (nowcoder.com) 题意&#xff1a; 思路&#xff1a; 注意细节 ai1时特判 枚举时最好枚举 i Code&#xff1a; #include <bits/stdc.h>//#define int long longusing namespace std;const int mxn1e610; const int mxe1e510; const int m…

Spring面试题--SpringBoot自动配置原理

注解解析 面试回答 面试官&#xff1a;Springboot自动配置原理 候选人&#xff1a; 嗯&#xff0c;好的&#xff0c;它是这样的。 在Spring Boot项目中的引导类上有一个注解SpringBootApplication&#xff0c;这个 注解是对三个注解进行了封装&#xff0c;分别是&#xff1a;…

手写Spring底层原理

一.创建maven项目 二.创建对应的文件夹&#xff0c;分别是spring和nickel 说明&#xff1a;spring文件夹用于存放spring相关的文件&#xff0c;nickel用于存放相应的配置文件和相关被spring加载的bean对象。 三.创建对对应的文件 3.1创建CommponentScan注解文件 package com…

网工内推 | 国内知名云服务商,IE证书优先,最高18k*15薪

01 UCloud 招聘岗位&#xff1a;网络工程师 职责描述&#xff1a; 1、负责UCloud全球骨干网或数据中心网络工作&#xff0c;包括设备技术选型、架构运营方案设计、日常运维支持&#xff1b; 2、持续提升网络稳定性与性能。 任职要求&#xff1a; 1、本科及以上学历&#xff…

Vue中使用 file-saver 实现导出excel文件

1、先下载一波 file-saver yarn add file-saver 2、封装导出-接口的请求 需要修改请求的数据类型 responsetype 的值为 blob responsetype 默认值是 json 可省略不写 // 导出excel export function exportExcel() {return http({url: /sys/user/export,responseType: b…

TOPSIS法

优劣解距离法&#xff1a;评价类模型&#xff0c;有准确的评判标准后得到评分。 构造计算评分的公式&#xff1a; (x-min)/(max-min) 或(x-min)/((max-x)(x-min)) 指标类型 极大型指标&#xff1a;越大越好。 极小型指标&#xff1a;越小越好。 中间性指标&#xff1a;既…

JavaWeb实现学生管理系统

JavaWeb实现学生管理系统 一、项目介绍二、项目结构三、前期准备1.配置maven环境&#xff0c;在pom.xml配置文件中配置项目所依赖的jar包2.在MySql数据库中&#xff0c;创建登录注册表login和学生信息表student&#xff08;1&#xff09;登录注册表login&#xff08;2&#xff…

【C++】继承 | 基类和派生类对象赋值转换 | 派生类的默认成员函数 | 菱形继承

目录 1.继承的概念及定义 1.1继承的概念 1.2 继承定义 1.2.1定义格式 1.2.2继承关系和访问限定符 1.2.3继承基类成员访问方式的变化 2.基类和派生类对象赋值转换 3.继承中的作用域 4.派生类的默认成员函数 5.继承与友元 6. 继承与静态成员 7. 菱形继承 1.继承的概念…

【InsCode Stable Diffusion美图活动一期】——海边跳舞的少女

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…

window平台下MSVC2015编译Libyuv静态库 动态库

window平台下MSVC2015编译Libyuv静态库 动态库 编译步骤一、环境准备1.1 下载libyuv源码1.2 下载安装cmake&#xff1a;1.3 安装MobaXterm&#xff08;终端工具&#xff09; 二、编译生成静态&#xff0c;动态库2.1 cmake编译生成Visual Studio工程2.2 使用Visual Studio打开YU…

怎么从视频中提取音频?分享三个方法给大家!

如何从视频中提取音频&#xff1f;当我们观看视频时&#xff0c;经常会听到很好听的音乐&#xff0c;或者希望下载视频课程的音频以便随时学习。有时候&#xff0c;某些音频可能没有单独的音源或无法下载。那么&#xff0c;有什么方法可以将视频中的音频提取出来呢&#xff1f;…

第五章:Mask R-CNN网络详解

(目标检测篇&#xff09;系列文章目录 第一章:R-CNN网络详解 第二章:Fast R-CNN网络详解 第三章:Faster R-CNN网络详解 第四章:SSD网络详解 第五章:Mask R-CNN网络详解 第六章:YOLO v1网络详解 第七章:YOLO v2网络详解 第八章:YOLO v3网络详解 文章目录 系列文章目录技…

Openlayers实战:自定义放大缩小,显示zoom等级

Openlayers地图中,默认的zoom组件是在左上角,这个组件很重要,方便大家来操控地图。在实际项目中,大家往往要改写这个组件,通常会放置到右下角,方便鼠标操作。 在我们的实战课程里,自定义了放大缩小,并增加了显示zoom等级的功能,实际的项目中往往都是这样办理的。 效果…

4、CCesium鼠标点击事件

在地图中添加鼠标点击事件&#xff0c;与web端cesium基本类似&#xff0c;我们使用上一个的示例&#xff0c;在上一个的示例中进行修改。 1、建一个类Handler&#xff0c;类中又个静态函数mouseUp&#xff0c;函数只在控制台输出信息 2、声明变量handler&#xff0c;并创建Scr…