LeetCode 0572.另一棵树的子树:深搜+广搜(n^2做法就能过,也有复杂度耕地的算法)

news2024/11/16 0:32:52

【LetMeFly】572.另一棵树的子树:深搜+广搜(n^2做法就能过,也有复杂度耕地的算法)

力扣题目链接:https://leetcode.cn/problems/subtree-of-another-tree/

给你两棵二叉树 rootsubRoot 。检验 root 中是否包含和 subRoot 具有相同结构和节点值的子树。如果存在,返回 true ;否则,返回 false

二叉树 tree 的一棵子树包括 tree 的某个节点和这个节点的所有后代节点。tree 也可以看做它自身的一棵子树。

 

示例 1:

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

示例 2:

输入:root = [3,4,5,1,2,null,null,null,null,0], subRoot = [4,1,2]
输出:false

 

提示:

  • root 树上的节点数量范围是 [1, 2000]
  • subRoot 树上的节点数量范围是 [1, 1000]
  • -104 <= root.val <= 104
  • -104 <= subRoot.val <= 104

解题方法:深搜+广搜(硬匹配)

如何判断两个树是否相同呢?

我们可以写一个函数isSame(rootA, rootB)来判断以rootA为根的树是否和以rootB为根的树相同。

首先如果rootA和rootB中有一个为空,那么他们都要为空才能相等;

否则(都不为空),rootA的值必须和rootB的值相等,并且他们的左子树相等(可递归判断),右子树也相等,两棵树才能相同。

因此,我们可以遍历以root为根的这棵树的每一个节点(深搜和广搜都可,本题解中C++代码以广搜为例,Python代码以深搜为例),判断以每个节点为根的树是否和以subRoot为根的树相同。一旦存在相同的子树,则立即返回true。

  • 时间复杂度 O ( s i z e ( r o o t ) × s i z e ( s u b R o o t ) ) O(size(root)\times size(subRoot)) O(size(root)×size(subRoot))
  • 空间复杂度 O ( s i z e ( r o o t ) ) O(size(root)) O(size(root))

AC代码

C++
class Solution {
private:
    bool isSame(TreeNode* a, TreeNode* b) {
        if (!a || !b) {
            return a == b;
        }
        return a->val == b->val && isSame(a->left, b->left) && isSame(a->right, b->right);
    }
public:
    bool isSubtree(TreeNode* root, TreeNode* subRoot) {
        queue<TreeNode*> q;
        q.push(root);
        while (q.size()) {
            TreeNode* thisNode = q.front();
            q.pop();
            if (isSame(thisNode, subRoot)) {
                return true;
            }
            if (thisNode->left) {
                q.push(thisNode->left);
            }
            if (thisNode->right) {
                q.push(thisNode->right);
            }
        }
        return false;
    }
};
Python
# from typing import Optional
# # Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right

class Solution:
    def isSame(self, a: Optional[TreeNode], b: Optional[TreeNode]) -> bool:
        if not a or not b:
            return a == b
        return a.val == b.val and self.isSame(a.left, b.left) and self.isSame(a.right, b.right)

    def isSubtree(self, root: Optional[TreeNode], subRoot: Optional[TreeNode]) -> bool:
        if not root:
            return False
        if self.isSame(root, subRoot):
            return True
        return self.isSubtree(root.left, subRoot) or self.isSubtree(root.right, subRoot)

解题方法拓展

假设两棵树的节点个数分别为m和n。

上述解题方法中,如果二叉树退化成链,且树中元素几乎全为1,则要比较接近 m n mn mn次。

有没有什么能提升效率的方法呢?其实我们在深搜以root为根的树的时候可以统计一下每个节点距其子树最远叶子节点的距离,只有高度相同的树才有可能相同。这样,每个节点不会被比较多次,我们就将时间复杂度降低到了 O ( m ) O(m) O(m)。(如果 n > m n\gt m n>m则不会比完全以subRoot为根节点的树的节点)

同步发文于CSDN和我的个人博客,原创不易,转载经作者同意后请附上原文链接哦~

Tisfy:https://letmefly.blog.csdn.net/article/details/140939018

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

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

相关文章

DEBUG:sw模板不对

问题 sw自带模板不合适 解决 工具 选项 文件位置 自己新建一个文件夹 放入模板 &#xff08;三维 二维各一个 一般就是统一标准 可以自己新建个模板&#xff09;

深度学习笔记(神经网络+VGG+ResNet)

深度学习 主要参考博客常用英语单词 概念应用神经网络基础神经网络基本结构 超参数超参数是什么常用超参数超参数搜索过程常用超参数调优办法&#xff08;通过问题复杂度和计算资源选择&#xff09; 激活函数介绍为什么要使用激活函数推荐博客 sigmoid激活函数&#xff08;使用…

【教程-时间序列预测】PyTorch 时间序列预测入门

文章目录 from博客: https://zhajiman.github.io/post/pytorch_time_series_tutorial/#%E9%AB%98%E7%BA%A7%E6%96%B9%E6%B3%95%E8%87%AA%E5%9B%9E%E5%BD%92%E6%A8%A1%E5%9E%8B 数据集产生 窗口 也是难点&#xff01;

工作中,如何有效解决“冲突”?不回避,不退让才是最佳方式

职场里每个人都在争取自己的利益&#xff0c;由于立场的不同&#xff0c;“冲突”不可避免。区别在于有些隐藏在暗处&#xff0c;有些摆在了台面上。 隐藏在“暗处”的冲突&#xff0c;表面上一团和气&#xff0c;实则在暗自较劲&#xff0c;甚至会有下三滥的手段&#xff1b;…

常见API(二)

API 应用程序编程接口&#xff0c;提高编程效率。本次学习了Object类&#xff0c;Objects工具类&#xff0c;包装类&#xff0c;StringBuilder&#xff0c;StringBuffer&#xff0c;和StringJoiner。 目录 1.Object 常见方法&#xff1a; 2.Objects 常见方法&#xff1a; 3…

AcWing开放地址法和拉链法

开放地址法&#xff0c;把h数组全部设置为3f&#xff0c;然后设定null为0x3f3f3f3f&#xff0c;find函数设定返回值t&#xff0c;如果h[t]null,那么x在h中不存在&#xff0c;否则为存在 #include<iostream> #include<cstring> #include<string> #define LEN…

在Vue3中如何为路由Query参数标注类型

前言 最近发布了一款支持IOC容器的Vue3框架&#xff1a;Zova。与以往的OOP或者Class方案不同&#xff0c;Zova在界面交互层面仍然采用Setup语法&#xff0c;仅仅在业务层面引入IOC容器。IOC容器犹如一把钥匙&#xff0c;为我们打开了业务工程化的大门&#xff0c;允许我们探索…

Linux网络编程2

TCP编程 顺序图 socket() 函数 socket()函数用于创建一个新的套接字。它是进行网络编程的第一步&#xff0c;因为所有的网络通信都需要通过套接字来进行。 原型&#xff1a; #include <sys/socket.h> int socket(int domain, int type, int protocol); domain&…

使用Go语言绘制饼图的教程

使用Go语言绘制饼图的教程 在本教程中&#xff0c;我们将学习如何使用Go语言及gg包绘制饼图&#xff0c;并将其保存为PNG格式的图片。饼图是一种常用的数据可视化图表&#xff0c;用于展示数据的比例关系和组成部分。 安装gg包 首先&#xff0c;确保你已经安装了gg包。如果还…

前端的学习-CSS(七)

一&#xff1a;定位(position) 1&#xff1a;为什么使用定位。 有一些固定的盒子&#xff0c;并且压在其他盒子上面&#xff0c;一些网页&#xff0c;会有固定的窗口&#xff0c;这些是标准流和浮动无法解决的&#xff0c;比如下面的例子。旁边的红色边框的效果是不会随着页面的…

汇昌联信数字做拼多多运营怎么入行?

拼多多作为中国领先的电商平台之一&#xff0c;近年来在数字运营领域展现出了强大的生命力和创新能力。汇昌联信数字作为一个潜在的新入行者&#xff0c;如何进入拼多多的运营领域&#xff0c;成为业界关注的焦点。本文旨在探讨汇昌联信数字如何通过有效的策略和方法&#xff0…

hal库回调函数机制

1. 第一行就是标准库函数的 在 nvic那个中断向量表里面的函数 以前写的都是 在中断向量表里面把这个中断处理函数重写 2. 第二行 第三行 的 hal库就是 通过中断向量表里面的这个函数 &#xff0c;再一次调用hal自己的中断回调函数&#xff0c;就是相当于多封装了两层 这个图更…

局部整体(二)利用python绘制维恩图

局部整体&#xff08;二&#xff09;利用python绘制维恩图 维恩图&#xff08; Venn Diagram&#xff09;简介 维恩图显示集与集之间所有可能存在的逻辑关系&#xff0c;每个集通常以一个圆圈表示&#xff0c;每个集都是一组具有共同之处的物件或数据。当多个圆圈&#xff08;…

【Material-UI】File Upload Button 组件详解

文章目录 一、基础实现1. component"label"2. 隐藏的输入元素 二、样式和交互增强1. 自定义按钮样式2. 交互提示 三、支持多文件上传四、无障碍性&#xff08;Accessibility&#xff09;1. 提供 aria-label 或 aria-labelledby2. 支持键盘导航 五、高级用法和集成1. …

leetcode-215. 数组中的第K个最大元素

题目描述 给定整数数组 nums 和整数 k&#xff0c;请返回数组中第 k 个最大的元素。 请注意&#xff0c;你需要找的是数组排序后的第 k 个最大的元素&#xff0c;而不是第 k 个不同的元素。 你必须设计并实现时间复杂度为 O(n) 的算法解决此问题。 示例 1: 输入: [3,2,1,5…

STM32-低功耗模式详解

一、概述 低功耗模式&#xff08;Low Power Mode&#xff09;是为了减少电子设备的能耗而设计的操作模式&#xff0c;广泛应用于依赖电池供电的设备中&#xff0c;旨在延长电池寿命或减少能源消耗。在用户需要设备长时间工作或在电量极为有限的情况下非常实用&#xff0c;虽然牺…

如何在IDEA上使用JDBC编程【保姆级教程】

目录 前言 什么是JDBC编程 本质 使用JDBC编程的优势 JDBC流程 如何在IEDA上使用JDBC JDBC编程 1.创建并初始化数据源 2.与数据库服务器建立连接 3.创建PreparedStatement对象编写sql语句 4.执行SQL语句并处理结果集 executeUpdate executeQuery 5.释放资源 前言 在…

yandex 不定长旋转验证码PPOCR识别案例

注意,本文只提供学习的思路,严禁违反法律以及破坏信息系统等行为,本文只提供思路 如有侵犯,请联系作者下架 某yandex 不定长旋转验证码如下: 可以看到,此种验证码非常变态,旋转角度不固定,干扰背景不固定,字符长度不固定,弯曲形变都是不固定的,在人眼都很难分辨验证…

『 C++ 』异常

文章目录 异常概念及使用自定义类型的异常C 标准库的异常体系异常的重新抛出异常安全异常规范异常的优缺点 异常概念及使用 C语言常见的错误处理机制如下: 返回值约定 通过定义一些列的返回值以及其对应的错误信息表述,通过不同的返回值来查看当前函数是否与调用成功; 通常情…

锂电池生产工艺数字化的业务架构.pptx

搜索《方案驿站》公众号进行下载。