【Leetcode】二叉树基础题思路

Alt

🔥个人主页Quitecoder

🔥专栏Leetcode刷题

Alt

目录

  • 1.单值二叉树
  • 2.相同的树
  • 3.对称二叉树
  • 4.另一棵树的子树

1.单值二叉树

题目链接:965.单值二叉树
题目描述
在这里插入图片描述

单值二叉树是所有节点的值都相同的二叉树。实现这个检查的思路是通过递归方式遍历整棵树,并验证每个节点是否满足单值二叉树的条件

具体来说,递归函数 isUnivalTree 的工作流程如下:

  1. 基本情况:
    • 如果当前节点 (root) 为空 (NULL),那么根据单值树的定义,它是单值的,因此返回 true
if(root==NULL)
{
   return true;
}
  1. 检查左子树:
    • 如果存在左子节点 (root->left),则进行两个检查:
      • 首先检查当前节点的值 (root->val) 是否与左子节点的值 (root->left->val) 相同。如果不相同,则整个树不可能是单值的,返回 false
      • 如果当前节点的值与左子节点的值相同,则递归调用 isUnivalTree(root->left) 来检查左子树是否为单值。如果左子树不是单值的,同样返回 false
if (root->left)
{
    if (root->val != root->left->val || !isUnivalTree(root->left))
        return false;
}
  1. 检查右子树:
    • 如果存在右子节点 (root->right),则进行类似的检查:
      • 检查当前节点的值 (root->val) 是否与右子节点的值 (root->right->val) 相同。如果不相同,返回 false
      • 如果当前节点的值与右子节点相同,则递归调用 isUnivalTree(root->right) 来检查右子树是否为单值。如果右子树不是单值的,同样返回 false
if (root->right)
{
    if (root->val != root->right->val || !isUnivalTree(root->right))
        return false;
}
  1. 返回结果:
    • 如果当前节点的值与它的子节点(如果有)都相同,并且子树也都是单值的,则返回 true,表示到目前为止,当前节点所在的子树是单值的。

总代码如下:

class Solution {
public:
    bool isUnivalTree(TreeNode* root) {
        if(root==NULL)
        {
            return true;
        }
        if(root->left)
        {
            if(root->val!=root->left->val||!isUnivalTree(root->left))
            return false;
        }
        if(root->right)
        {
            if(root->val!=root->right->val||!isUnivalTree(root->right))
            return false;
        }
        return  true;
    }
};

通过以上的递归过程,我们可以从根节点开始检查整棵树。只有当所有的节点与它们的子节点(如果有)都具有相同的值,并且所有的子树都是单值的时候,这棵树才是单值的。这种方法有效地使用了分治策略,将大问题分解成多个小问题,递归地解决每一个小问题

2.相同的树

题目链接:100.相同的树
题目描述在这里插入图片描述

这段代码实现的是一个用于检查两棵二叉树是否相同的函数 isSameTree。相同指的是两棵树具有相同的结构,且对应位置上的节点具有相同的值

函数 isSameTree 通过递归的方法来比较给定的两棵树 pq 的节点。递归的基本思路是从两棵树的根节点开始比较,然后依次递归地比较它们的左子树和右子树。具体步骤如下:

  1. 检查基本情况:
    • 如果两个节点 pq 都是 nullptr,即都不存在,那么它们被视为相同,因此返回 true
    • 如果其中一个节点是 nullptr 而另一个不是(使用或操作符 || 判断),那么两棵树在结构上不相同,因此返回 false
if(p==NULL&&q==NULL)return true;
if(p==NULL||q==NULL)return false;
  1. 比较节点值:
    • 如果两个节点都存在,那么接着比较它们的值(p->valq->val)。如果值不相同,树不相同,返回 false
if(p->val!=q->val)return false;
  1. 递归比较子树:
    • 如果到目前为止两个节点相同(即它们存在且值相同),继续递归比较左子树 p->leftq->left,以及右子树 p->rightq->right
    • 使用逻辑与操作符 && 来确保两个递归调用的结果都为 true。这意味着两个左子树和两个右子树都必须分别相同,整个树才相同
return isSameTree(p->left,q->left)&&isSameTree(p->right,q->right);

如果所有对应的节点都满足结构相同且值相同的条件,递归过程最终会在所有叶子节点处结束。在这种情况下,函数返回 true,表明两棵树确实相同。如果任何节点不相同,函数会在那一点上返回 false

代码如下:

class Solution {
public:
    bool isSameTree(TreeNode* p, TreeNode* q) {
        if(p==NULL&&q==NULL)return true;
        if(p==NULL||q==NULL)return false;
        if(p->val!=q->val)return false;
        return isSameTree(p->left,q->left)&&isSameTree(p->right,q->right);
    }
};

3.对称二叉树

题目链接:101.对称二叉树
题目描述在这里插入图片描述
在这里插入图片描述

这道题与上一道题思路十分类似

这道题isSymmetric 函数是这个功能的入口点,它提供了一个参数,而需要进行比较两个子树,我们需要提供两个参数,我们在这里自己构建一个子函数

 bool _isSymmetric(TreeNode*root1,TreeNode*root2)

_isSymmetric 函数通过以下步骤递归地比较两个给定的树(或子树)root1root2

  1. 检查基本情况:
    • 如果 root1root2 都是空(NULL),说明它们是对称的(或者都是叶子节点),返回 true
    • 如果其中一个为空而另一个不为空,说明在这一层上树不对称,返回 false
if(root1==NULL&&root2==NULL)return true;
if(root1==NULL||root2==NULL)return false;
  1. 比较节点值:
    • 如果两个节点都非空,首先比较它们的值 (root1->valroot2->val)。如果节点值不相同,树不对称,返回 false
if(root1->val!=root2->val) return false;
  1. 递归比较镜像子树:
    • 递归比较 root1 的左子树与 root2 的右子树,以及 root1 的右子树与 root2 的左子树。这两对子树必须分别是镜像对称的,整个树才是对称的。
    • 使用 && 运算符确保上述两个递归调用必须都为 true 才返回 true
return _isSymmetric(root1->left,root2->right)&&_isSymmetric(root1->right,root2->left);

isSymmetric 函数在被调用时,以给定树的根节点 root 的两个子节点 root->leftroot->right 作为参数来调用 _isSymmetric这对于开始对称性检查是合适的,因为对于树的根节点,我们要验证的是它的两个子节点是不是彼此的镜像

总代码如下:

class Solution {
public:
    bool _isSymmetric(TreeNode*root1,TreeNode*root2)
    {
        if(root1==NULL&&root2==NULL)return true;
        if(root1==NULL||root2==NULL)return false;
        if(root1->val!=root2->val) return false; 
        return _isSymmetric(root1->left,root2->right)&&_isSymmetric(root1->right,root2->left);
    }
    bool isSymmetric(TreeNode* root) {
            
         return _isSymmetric(root->left,root->right);
    }
};

4.另一棵树的子树

题目链接:572.另一棵树的子树
题目描述在这里插入图片描述

为了判断一棵树 subRoot 是否是另一棵树 root 的子树,我们需要遍历 root 并找到一个节点,该节点与 subRoot 的树根具有相同的值。一旦找到这样的节点,我们就需要检查从这个节点开始的子树是否与 subRoot 完全相同。上面 isSameTree 函数可以用来完成这个检查,因为它能够确定两棵树是否相同

实现 isSubtree 函数的步骤:

  1. 遍历 root 树。我们可以使用递归方式进行前序遍历(根节点 -> 左子树 -> 右子树)

  2. 在每个节点,使用 isSameTree 函数来检查以当前 root 中的节点为根的子树是否与 subRoot 树相同

  3. 如果 isSameTree 返回 true,说明 subRootroot 的子树。否则,继续遍历 root 的左右子节点

isSubtree 完整实现:

class Solution {
public:
    bool isSameTree(TreeNode* p, TreeNode* q) {
        if(p==NULL && q==NULL) return true;
        if(p==NULL || q==NULL) return false;
        if(p->val != q->val) return false;
        return isSameTree(p->left, q->left) && isSameTree(p->right, q->right);
    }

    bool isSubtree(TreeNode* root, TreeNode* subRoot) {
        if (subRoot == NULL) return true;
        if (root == NULL) return false;
        if (isSameTree(root, subRoot)) return true;
        return isSubtree(root->left, subRoot) || isSubtree(root->right, subRoot);
    }
};

在实现 isSubtree 时,我们要注意几个基本的边界条件:

  • 如果 rootsubRoot 都为空,那么 subRootroot 的子树。
  • 如果 root 为空而 subRoot 不为空,那么 subRoot 不可能是 root 的子树。
  • 如果 rootsubRoot 的根节点值相同,我们需要使用 isSameTree 函数来检查它们是否结构和值完全相同。
  • 如果在当前节点没有找到与 subRoot 相同的子树,那么应该在 root 的左子树和右子树中继续寻找可能的匹配

本节内容到此结束!感谢阅读!

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

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

相关文章

MySQL LIKE通配符(%,_)及escape实例讲解

LIKE操作符常用于模式匹配查询数据。以正确的方式使用LIKE运算符对于提高查询性能至关重要。 LIKE操作符允许您从基于指定的模式选择表中的数据。因此,LIKE操作符经常用于SELECT语句的WHERE子句中。 MySQL提供了两个通配符与LIKE操作符一起使用:百分比…

LeetCode 98.验证二叉搜索树

题目描述 给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。 有效 二叉搜索树定义如下: 节点的左 子树 只包含 小于 当前节点的数。节点的右子树只包含 大于 当前节点的数。所有左子树和右子树自身必须也是二叉搜索树。 示例 1&#xff…

移植 SquareLine 导出的 UI 源码到 HMI-Board

目录 准备工具创建 HMI 工程设计 UIUI 移植板级验证更多内容 HMI-Board 为 RT-Thread 联合瑞萨推出的高性价比图形评估套件,取代传统的 HMI 主控板 硬件,一套硬件即可实现 HMI IoT 控制 的全套能力。依托于瑞萨高性能芯片 RA6M3 及 RT-Thread 软件生态…

leetcode870.优势洗牌

题目描述: 给定两个长度相等的数组 nums1 和 nums2,nums1 相对于 nums2 的优势可以用满足 nums1[i] > nums2[i] 的索引 i 的数目来描述。 返回 nums1 的任意排列,使其相对于 nums2 的优势最大化。 示例一: 输入&#xff…

nginx--平滑升级

失败了,等我拍好错继续更新 命令 选项说明 帮助: -? -h 使用指定的配置文件: -c 指定配置指令:-g 指定运行目录:-p 测试配置文件是否有语法错误:-t -T 打印nginx的版本信息、编译信息等:-v -V 发送信号: -s 示例: nginx -s reload 信号说明 立刻停止服务:stop,相…

笔记:编写程序,绘制一个展示支付宝月账单报告的饼图,

文章目录 前言一、饼图是什么?二、分析题目三、编写代码总结 前言 编写程序,绘制一个展示支付宝月账单报告的饼图,实现过程如下: (1) 导入 matplotlib.pyplot 模块; (2)…

主成分分析在R语言中的简单应用:使用mvstats包

在数据科学领域,主成分分析(PCA)是一种广泛使用的技术,主要用于数据降维和探索性数据分析。PCA可以帮助我们发现数据中的模式,减少数据集的复杂性,同时保持数据中最重要的特征。本文将介绍如何在R语言中使用…

【经典算法】LeetCode112. 路径总和(Java/C/Python3/Go实现含注释说明,Easy)

作者主页: 🔗进朱者赤的博客 精选专栏:🔗经典算法 作者简介:阿里非典型程序员一枚 ,记录在大厂的打怪升级之路。 一起学习Java、大数据、数据结构算法(公众号同名) ❤️觉得文章还…

实时监控RTSP视频流并通过YOLOv5-seg进行智能分析处理

在完成RTSP推流之后,尝试通过开发板接收的视频流数据进行目标检测,编写了一个shell脚本实现该功能,关于视频推流和rknn模型的部署请看之前的内容或者参考官方的文档。 #!/bin/bash # 设置脚本使用的shell解释器为bashSEGMENT_DIR"./seg…

OceanBase开发者大会实录-陈文光:AI时代需要怎样的数据处理技术?

本文来自2024 OceanBase开发者大会,清华大学教授、蚂蚁技术研究院院长陈文光的演讲实录—《AI 时代的数据处理技术》。完整视频回看,请点击这里>> 大家好,我是清华大学、蚂蚁技术研究院陈文光,今天为大家带来《AI 时…

JUC线程

进程和线程: 进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配的基本单位,是操作系统结构的基础。 线程(英语:thread)是操作系统能够进行运算调度…

python基础语法--函数

一、函数概述 函数就是执行特定任务完成特定功能的一段代码。可以在程序中将某一段代码定义成函数,并指定一个函数名和接收的输入(参数),这样就可以在程序的其他地方通过函数名多次调用并执行该段代码了。 每次调用执行后&#…

Ubuntu如何安装Calicoctl

在 Ubuntu 上安装 Calico 通常涉及几个步骤。以下是一般的安装过程: 安装 etcd 或使用 Kubernetes 集群的现有 etcd: 如果你使用的是独立的 etcd,请确保 etcd 在可访问的地方运行。如果你使用的是 Kubernetes 集群,通常会有一个 e…

用户中心(终)

文章目录 Ant Design Pro(Umi 框架)ProComponents 高级表单待优化点 todo注册逻辑增加注册页面页面重定向问题注册页面 **获取用户的登录态****前端用户管理功能** Ant Design Pro(Umi 框架) app.tsx 项目全局入口文件&#xff0c…

【车载开发系列】MCAL基本概念

【车载开发系列】MCAL基本概念 【车载开发系列】MCAL基本概念 【车载开发系列】MCAL基本概念一. BSW与MCAL1)BSW-服务层2)BSW-ECU抽象层3)MCAL驱动层 二. MCAL基本概念三. MCAL组成1)PORT2)DIO3)ADC4&#…

排序算法——直接插入排序

直接插入排序与希尔排序是插入排序的两个分支,直接插入排序是较为简单的一种排序算法,同时也是众多算法实现或优化的基石。 前提: 插入排序:有一个已经有序的数据序列,要求在这个已经排好的数据序列中插入一个数&…

BigKey的危害

1.2.1、BigKey的危害 网络阻塞 对BigKey执行读请求时,少量的QPS就可能导致带宽使用率被占满,导致Redis实例,乃至所在物理机变慢 数据倾斜 BigKey所在的Redis实例内存使用率远超其他实例,无法使数据分片的内存资源达到均衡 Redis阻…

nginx--自定义日志跳转长连接文件缓存状态页

自定义日志服务 [rootlocalhost ~]# cat /apps/nginx/conf/conf.d/pc.conf server {listen 80;server_name www.fxq.com;error_log /data/nginx/logs/fxq-error.log info;access_log /data/nginx/logs/fxq-access.log main;location / {root /data/nginx/html/pc;index index…

C/C++ BM33 二叉树的镜像

文章目录 前言题目解决方案一1.1 思路阐述1.2 源码 总结 前言 镜像说的好听,无非就是换下节点。 题目 操作给定的二叉树,将其变换为源二叉树的镜像。 数据范围:二叉树的节点数 0 ≤ n ≤ 1000 0≤n≤1000 0≤n≤1000, 二叉树每…

ThreeJS:本地部署官网文档与案例

部署方式 部署之前请确保已经配置好node.js环境。 1. 下载ThreeJS源码 ThreeJS的GitHub地址:GitHub - mrdoob/three.js: JavaScript 3D Library.,可以简单查看ThreeJS当前版本:r164, 我们可以选择对应的版本(此处为r1…