【面试经典150 | 二叉树】相同的树

文章目录

  • 写在前面
  • Tag
  • 题目来源
  • 题目解读
  • 解题思路
    • 方法一:递归
    • 方法二:迭代
  • 写在最后

写在前面

本专栏专注于分析与讲解【面试经典150】算法,两到三天更新一篇文章,欢迎催更……

专栏内容以分析题目为主,并附带一些对于本题涉及到的数据结构等内容进行回顾与总结,文章结构大致如下,部分内容会有增删:

  • Tag:介绍本题牵涉到的知识点、数据结构;
  • 题目来源:贴上题目的链接,方便大家查找题目并完成练习;
  • 题目解读:复述题目(确保自己真的理解题目意思),并强调一些题目重点信息;
  • 解题思路:介绍一些解题思路,每种解题思路包括思路讲解、实现代码以及复杂度分析;
  • 知识回忆:针对今天介绍的题目中的重点内容、数据结构进行回顾总结。

Tag

【递归】【迭代】【二叉树】


题目来源

100. 相同的树


题目解读

判断两棵二叉树是否相同,相同不仅要在结构上相同还要在对应节点值上相同。


解题思路

有两种解决思路,一是递归而是迭代。

在真正理解的递归的含义之后,会发现不论是从代码量还是思考量递归算法都更胜一筹。而迭代虽易于理解,但是代码量较大。

方法一:递归

思路

我们从根节点开始判断两棵二叉树是否相同,可以发现如果根节点的值相同,并且结构相同(左右子树都有),那么只需要判断两棵树的左右子树是否相同即可。

标准的大问题转化成了子问题,都是判断两棵树是否相同,只是范围缩小了。于是可是使用递归来解题。

递归出口是什么?

递归出口换言之就是可以直接进行判断的情况,包括:

  • 节点都为空,此时可以直接返回 true
  • 一个节点为空,另一个不为空,返回 false
  • 节点值不相等,返回 false

大问题与子问题的如何链接?

本题是判断二叉树是否相同,如果对应的子二叉树不同,则 “大” 二叉树也不同。

算法

我们从根节点开始递归,递归函数为:

  • 递归出口,见上述对递归出口的描述;
  • 递归比较左子树和右子树,“大问题” 的比较结果即为小问题的比较结果。
/**
 * 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 isSameTree(TreeNode* p, TreeNode* q) {
        if(p == nullptr && q == nullptr){
            return true;
        }
        else if(p == nullptr || q == nullptr){
            return false;
        }
        else if(p->val != q->val){
            return false;
        }
        else{
            return isSameTree(p->left, q->left) && isSameTree(p->right, q->right);
        }
    }
};

复杂度分析

时间复杂度: O ( m i n ( m , n ) ) O(min(m, n)) O(min(m,n)) m m m n n n 分别为两个二叉树的节点数。

空间复杂度: O ( m i n ( m , n ) ) O(min(m, n)) O(min(m,n))

方法二:迭代

思路

递归是隐式的进行比较,而迭代是显示的比较。

通过迭代判断两个二叉树是否相同。同样首先判断两个二叉树是否为空,如果两个二叉树都不为空,则从两个二叉树的根节点开始广度优先搜索。

接着使用两个队列分别按层存储两棵二叉树的节点。初始时将两个两棵树的根节点分别加入两个队列。每次从两个队列各取出一个节点,进行如下比较操作:

  • 比较两个节点的值,如果两个节点的值不相同则两棵二叉树一定不同;
  • 如果两个节点的值相同,则判断两个节点的子节点是否为空,如果只有一个节点的左子节点为空,或者只有一个节点的右子节点为空,则两个两棵树的结构不同,因此两棵二叉树一定不同;
  • 如果两个节点的子节点的结构相同,则将两棵节点的非空子节点分别加入两个队列,子节点加入队列时需要注意顺序,如果左右子节点都不为空,则先加入左子节点,后加入右子节点。

如果搜索结束时两个队列同时为空,则两棵二叉树相同。如果只有一个队列为空,则两棵二叉树的结构不同,因此两棵二叉树不同。

算法

/**
 * 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 isSameTree(TreeNode* p, TreeNode* q) {
        if(p == nullptr && q == nullptr){
            return true;
        }
        else if(p == nullptr || q == nullptr){
            return false;
        }

        queue<TreeNode*> q1, q2;
        q1.push(p);
        q2.push(q);
        
        while(!q1.empty() && !q2.empty()){
            TreeNode* now1 = q1.front();
            q1.pop();
            TreeNode* now2 = q2.front();
            q2.pop();

            // 两个节点值不同
            if(now1->val != now2->val){
                return false;
            }

            auto left1 = now1->left, right1 = now1->right, left2 = now2->left, right2 = now2->right;
            // 左/右子树一个为空,另一个不为空
            if((left1 == nullptr) ^ (left2 == nullptr)){
                return false;
            } 
            if((right1 == nullptr) ^ (right2 == nullptr)){
                return false;
            }
            
            // 更新队列
            if(left1)  q1.push(left1);
            if(right1) q1.push(right1);
            if(left2)  q2.push(left2);
            if(right2) q2.push(right2);
        }
        return q1.empty() && q2.empty();
    }
};

复杂度分析

时间复杂度: O ( m i n ( m , n ) ) O(min(m, n)) O(min(m,n)) m m m n n n 分别为两个二叉树的节点数。

空间复杂度: O ( m i n ( m , n ) ) O(min(m, n)) O(min(m,n))


写在最后

如果文章内容有任何错误或者您对文章有任何疑问,欢迎私信博主或者在评论区指出 💬💬💬。

如果大家有更优的时间、空间复杂度方法,欢迎评论区交流。

最后,感谢您的阅读,如果感到有所收获的话可以给博主点一个 👍 哦。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

python深浅拷贝

【 一 】Python 深拷贝和浅拷贝概念理解 个人见解&#xff1a; 浅拷贝&#xff0c;指的是重新分配一块内存&#xff0c;创建一个新的对象&#xff0c;但里面的元素是原对象中各个子对象的引用。 深拷贝&#xff0c;是指重新分配一块内存&#xff0c;创建一个新的对象&…

Post Quantum Fuzzy Stealth Signatures and Applications

目录 笔记后续的研究方向摘要引言贡献模块化框架模糊构造实施适用于FIDO Post Quantum Fuzzy Stealth Signatures and Applications CCS 2023 笔记 后续的研究方向 摘要 自比特币问世以来&#xff0c;基于区块链的加密货币中的私人支付一直是学术和工业研究的主题。隐形地址…

elasticsearch 内网下如何以离线的方式上传任意的huggingFace上的NLP模型(国内避坑指南)

es自2020年的8.x版本以来&#xff0c;就提供了机器学习的能力。我们可以使用es官方提供的工具eland&#xff0c;将hugging face上的NLP模型&#xff0c;上传到es集群中。利用es的机器学习模块&#xff0c;来运维部署管理模型。配合es的管道处理&#xff0c;来更加便捷的处理数据…

DSGN:用于 3D 目标检测的深度立体几何网络

论文地址&#xff1a;https://www.jianshu.com/go-wild?ac2&urlhttps%3A%2F%2Farxiv.org%2Fpdf%2F2001.03398v3.pdf 论文代码&#xff1a;https://github.com/chenyilun95/DSGN 论文背景 大多数最先进的 3D 物体检测器严重依赖 LiDAR 传感器&#xff0c;因为基于图像的方…

IDEA中表明或者字段找不到时报红

问题 idea 中mysql的sql语句报红&#xff0c;无论表名还是表字段 原因 是由于sql方言导致的 当我们选择某一个sql方言的时候&#xff0c;xml配置会按照指定规则校验sql是否规范&#xff0c;并给出提示 解决方案 取消sql方言&#xff0c;设置sql方言为None。设置完重启idea既…

理解网络通信中的关键因素-带宽

在今天的数字时代&#xff0c;我们经常听到“带宽”的词汇&#xff0c;尤其是在谈论互联网速度、网络连接和数据传输时。带宽是网络通信的关键概念&#xff0c;对于我们的在线体验至关重要。 带宽的定义 带宽是一个用于描述网络通信速度和容量的术语。它通常用于衡量网络连接…

解决firefox(火狐)浏览器使用transform: scale导致的border不显示或显示不全的问题;

最近火狐遇到了此问题&#xff0c;查了许久没有解决办法也有说是因为火狐不支持小于1px单位的&#xff0c;也有说火狐浏览器本身的问题&#xff0c;然后也没有解决方案&#xff0c;最后没办法只能用最笨的方法解决。。。。 只针对Firefox使用CSS&#xff0c;使用’-moz-documen…

层流燃烧模拟的技术研究与实践

层流燃烧模拟的技术研究与实践 一、引言 层流燃烧,作为一种基础而重要的燃烧类型,广泛存在于各种工业应用中,如发动机、燃气轮机、燃烧室等。为了更好地理解和优化这一过程,科研人员运用计算流体动力学(CFD)工具进行模拟,以期能更深入地洞察其内在机制。 二、层流燃烧…

MQTT 协议入门:轻松上手,快速掌握核心要点

文章目录 什么是 MQTT&#xff1f;MQTT 的工作原理MQTT 客户端MQTT Broker发布-订阅模式主题QoS MQTT 的工作流程开始使用 MQTT&#xff1a;快速教程准备 MQTT Broker准备 MQTT 客户端创建 MQTT 连接通过通配符订阅主题发布 MQTT 消息MQTT 功能演示保留消息Clean Session遗嘱消…

深度拷贝 deepClone

/*** 深度克隆对象* param {*} value 需要克隆的值 * param {WeakMap} cache 使用 WeakMap 解决环形引用问题&#xff0c;防止内存泄漏 */ function deepClone(value, cache new WeakMap()) {// 基础数据if(typeof value ! object || value null) {return value;}// 解决环形…

Enterprise Architect 12版本使用教程

Enterprise Architect 12版本使用教程 1.下载安装Enterprise Architect 122.Enterprise Architect原始DDL模板配置及存在的问题1.DDL Column Definition原始模板&#xff08;没有default值&#xff1a;可忽略&#xff09;2.DDL Data Type原始模板&#xff08;timestamp等时间字…

BCrypt加密解密工具类方法

BCrypt加密解密工具类方法 直接上代码 package com.loit.park.common.utils;import org.springframework.security.crypto.bcrypt.BCrypt;/*** author hanjinqun* date 2023/5/13* BCrypt工具类*/ public class BCryptUtils {/*** 加密*/public static String hashpw(String s…

【JavaEE进阶】 Spring使用注解存储对象

文章目录 &#x1f334;序言&#x1f340;前置⼯作&#xff1a;配置扫描路径&#x1f384;添加注解存储 Bean 对象&#x1f333;类注解&#x1f6a9;为什么要这么多类注解&#x1f6a9;注解之间的联系 &#x1f38b;⽅法注解 Bean&#x1f6a9;⽅法注解需要配合类注解使⽤ ⭕总…

C //习题10.8 将第7题结果仍存入原有的“stu_sort“文件而不另建立新文件。

C程序设计 &#xff08;第四版&#xff09; 谭浩强 习题10.8 习题10.8 将第7题结果仍存入原有的"stu_sort"文件而不另建立新文件。 IDE工具&#xff1a;VS2010 Note: 使用不同的IDE工具可能有部分差异。 说明&#xff1a;此题同习题10.7的代码&#xff0c;唯一的区…

大数据毕业设计之前端03:logo、menu的折叠展开实现

关键字&#xff1a;BuildAdmin、pinia、logo、aside、menu、菜单折叠、Vue、ElementUI 前言 上一篇文章中&#xff0c;借助aside的实现讲了一些开发的小技巧&#xff0c;以及css的解读。本篇文章主要写一下如何填充aside的内容。 aside主要是由两个部分组成的&#xff1a;log…

Mysql启动占用内存过高解决

Hi, I’m Shendi Mysql启动占用内存过高解决 前言 最近服务器内存不够用了&#xff0c;甚至还出现了内存溢出问题&#xff0c;导致程序宕机。但请求与用户量并没有多少&#xff0c;所以从各种启动的程序中想方设法的尽可能的减少其占用的内存。 而在我的服务器中&#xff0c;…

数字化和数智化一字之差,究竟有何异同点?

在2023杭州云栖大会的一展台内&#xff0c;桌子上放着一颗番茄和一个蛋糕&#xff0c;一旁的机器人手臂融入“通义千问”大模型技术后&#xff0c;变得会“思考”&#xff1a;不仅能描述“看”到了什么&#xff0c;还能确认抓取的是番茄而不是蛋糕。 “传统的机械臂通常都只能基…

从0到1,手把手带你开发截图工具ScreenCap------001实现基本的截图功能

ScreenCap---Version&#xff1a;001 说明 从0到1&#xff0c;手把手带你开发windows端的截屏软件ScreenCap 当前版本&#xff1a;ScreenCap---001 支持全屏截图 支持鼠标拖动截图区域 支持拖拽截图 支持保存全屏截图 支持另存截图到其他位置 GitHub 仓库master下的Scr…

二百一十四、Linux——Linux系统时间比电脑时间慢5分钟

一、目的 服务器重启后&#xff0c;发现Linux的系统时间比电脑时间慢5分钟&#xff0c;于是看了些博客&#xff0c;终于找到了解决方法&#xff0c;记录一下&#xff0c;以防止后面出现同样的问题 二、问题 通过date查看&#xff0c;Linux系统时间比电脑时间慢5分钟 &#…

solidworks打开图纸零件隐藏看不到怎么办?

solidworks打开图纸零件隐藏看不到怎么办&#xff1f;solidworks打开时看不到零件图像&#xff0c;显示空白文档&#xff0c;该怎么解决这个问题呢&#xff1f;下面我们就来看看详细的教程&#xff0c;需要的朋友可以参考下 1、打开SolidWorks &#xff0c;并选中需要打开的零…