【数据结构和算法】--- 二叉树(5)--二叉树OJ题

news2025/1/18 1:52:41

目录

  • 一、二叉树OJ题
    • 1.1 单值二叉树
    • 1.2 检查两颗树是否相同
    • 1.3 对称二叉树
    • 1.4 另一颗树的子树
    • 1.5 平衡二叉树
  • 二、概念选择题

一、二叉树OJ题

1.1 单值二叉树

题目描述: 如果二叉树每个节点都具有相同的值,那么该二叉树就是单值二叉树。只有给定的树是单值二叉树时,才返回true;否则返回 false

做题链接: 965. 单值二叉树

解题思路:
我们可以利用递归分治的思想,将此问题分解为:根节点和左孩子的值是否相等(root->left->val != root->val),根节点和右孩子的值是否相等(root->right->val != root->val),左子树判断,右子树判断。
且在每次值相等判断之前都要 先确定,当前根节点是否为空(root == NULL),若为空就直接返回true表示相等。因为我们会不能确定当前节点的左右孩子是否为空节点,所以每次在比较当前节点和孩子节点的值的时候,都要先判断(root->left != NULLroot->right != NULL),以确保不会对空节点解引用。如果值不相等便返回false
最后一步便是继续递归当前节点的左子树(root->left)和右子树(root->right),那么如果左子树或右子树都为相同的值那么便返回true,如果有一个不相同便会返回false。既然这样,那么我们便可使用&&将递归左和右子树的函数连接起来(isUnivalTree(root->left) && isUnivalTree(root->right))。并将此结果作为返回值,只有同为true,才会真正的返回true

解题代码:

bool isUnivalTree(struct TreeNode* root) {
    if(root == NULL)
        return true;
    //左右孩子和当前节点的值的判断
    //1、先判孩子不为空; 2、再判孩子和根的值。
    if(root-> left != NULL && root->left->val != root->val)
        return false;
    if(root-> right != NULL && root->right->val != root->val)
        return false;
    //左右子树的递归判断
    return isUnivalTree(root->left) && isUnivalTree(root->right);
}

代码图解:
在这里插入图片描述

1.2 检查两颗树是否相同

题目描述: 给你两棵二叉树的根节点pq,编写一个函数来检验这两棵树是否相同。如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。

做题链接: 100. 相同的树

解题思路:
同样可以利用递归分治的思想:两棵二叉树根节点是否相同,左子树是否相同,右子树是否相同。 首先判断两棵二叉树的根节点是否为空,若都为空(p == NULL && q == NULL)则定为相等,返回true。但是如果只有一个节点是空节点的话,那么便要返回false,此处可以使用p == NULL || q == NULL来判断。
相信有人会问,这样判断的话如果两个都是空节点的话,那不就返回false了吗?当然不会,如果能从第一个判断出来,就说明不会出现都为空的情况,那么进入此if语句的条件就只有两个节点中的一个为空!
判断完空节点的情况,我们便可判断这两个节点的值是否相同,若不同则返回false。最后再递归两棵二叉树的左右子树,若两函数都为true,则最终返回true

解题代码:

bool isSameTree(struct TreeNode* p, struct 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);
}

代码图解:
在这里插入图片描述

1.3 对称二叉树

题目描述: 给你一个二叉树的根节点 root , 检查它是否轴对称。

做题链接: 101. 对称二叉树

解题思路:
在这里插入图片描述
看上面这个二叉树,如果我们将它分为,根节点,左子树,右子树。如果将左子树和右子树拆分开,那么判断对称二叉树,便可转化为检查两颗树是否相同!!
那么便可在1.2的基础上修改一下代码即可,即二叉树p的左子树和二叉树q的右子树是否相同,(isSameTree(p->left, q->right) && isSameTree(p->right, q->left)),因为两棵二叉树是镜像的关系。

解题代码:

//检查两颗树是否相同
bool isSameTree(struct TreeNode* p, struct TreeNode* q)
{
    if(!p && !q)
        return true;
    if(!p || !q)
        return false;
    if(q->val != p->val)
        return false;
    return isSameTree(p->left, q->right) && isSameTree(p->right, q->left);
}
//分出左右子树
bool isSymmetric(struct TreeNode* root) {
    return isSameTree(root->left, root->right);
}

1.4 另一颗树的子树

题目描述: 给你两棵二叉树 rootsubRoot 。检验 root 中是否包含和 subRoot具有相同结构和节点值的子树。如果存在,返回true ;否则,返回false
二叉树 tree的一棵子树包括 tree 的某个节点和这个节点的所有后代节点。tree也可以看做它自身的一棵子树。

做题链接: 572. 另一棵树的子树

解题思路:
此题思路任然与1.2检查两颗树是否相同,相似。若在root中寻找subRoot,那么便可以先判断当前二叉树rootsunRoot是否相似,若相似则返回true;不相似则继续递归root的左子树和右子树。 还需要注意的是,此处判断左右子树的函数使用||相连,因为只要左右子树中一个有subRoot即可。

解题代码:

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

1.5 平衡二叉树

做题链接: 110. 平衡二叉树

题目描述: 给定一个二叉树,判断它是否是高度平衡的二叉树。本题中,一棵高度平衡二叉树定义为:一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。

解题思路:
既然要判断左右子树的高度差,那么就要写出求二叉树的高度的函数。此函数实现思想:遇到空节点便返回0,然后递归左右子树,每递归一层便加一,返回左子树高度和右子树高度中的较大者,利用fmax()函数求较大值,具体思想还请参考图解:
在这里插入图片描述
基于上述求二叉树最大高度的函数BinaryTreeHeight,那么便可利用递归分治的思想:根节点下左右子树的高度差,根节点左孩子作为二叉树第一层的左右子树的高度差,根节点右孩子作为二叉树第一层的左右子树的高度差。
遇到空节点便返回true,先利用BinaryTreeHeight函数求出左子树(leftHeight)和右子树(rightHeight)的最大高度,然后比较高度差(abs(leftHeight - rightHeight) > 1),若大于一则返回false,最后再递归左右子树。

解题代码:

//求当前节点下的左子树和右子树高度,并返回较大值
int BinaryTreeHeight(struct TreeNode* root)
{
   if(root == NULL)
       return 0;
   int leftHeight = BinaryTreeHeight(root->left) + 1;
   int rightHeight = BinaryTreeHeight(root->right) + 1;
   return fmax(leftHeight, rightHeight);
}
//主函数
bool isBalanced(struct TreeNode* root) 
{
    if(root == NULL)
        return true;
    //左 右子树高度
    int leftHeight = BinaryTreeHeight(root->left);
    int rightHeight = BinaryTreeHeight(root->right);
    //差值判断
    if(abs(leftHeight - rightHeight) > 1)
        return false;
    //递归左右子树
    return isBalanced(root->left) && isBalanced(root->right);
}

二、概念选择题

  1. 在一颗完全二叉树中,某一个结点没有其左孩子,则该结点一定(B
    A.是根结点
    B.是叶结点
    C.是分支结点
    D.在倒数第二层

解析: 完全二叉树中如果一个节点没有左孩子,则一定没有右孩子,必定为一个叶子节点,最后一层一定为叶子节点,但是倒数第二层也可能存在叶子节点。

  1. 有n个元素的完全二叉树的深度是(D
    A.nlogn
    B.nlogn+1
    C.logn
    D.logn+1
  2. 在一颗度为3的树中,度为3的结点有2个,度为2的结点有1个,度为1的结点有2个,则叶子结点有(B)个。

解析: 设度为i的节点个数为ni。 该树总共有n个节点,则n=n0+n1+n2+n3。有n个节点的树的总边数为n-1条。根据度的定义,总边数与度之间的关系为:n-1=0*n0+1*n1+2*n2+3*n3。联立两个方程求解,可以得到n0 = n2 + 2n3 + 1, n0=6

  1. 下列关于二叉树的叙述错误的是( A
    A.二叉树指的是深度为 2 的树
    B.一个 n 个结点的二叉树将拥有 n-1 条边
    C.一颗深度为 h 的满二叉树拥有 2^h-1 个结点(根结点深度为1)
    D.二叉树有二叉链和三叉链两种表示方式

解析: A错误: 二叉树指最大孩子个数为2,即树的度为二的树。深度描述的为树的层数。
B正确:对于任意的树都满足:边的条数比节点个数少1,因为每个节点都有双亲,但是根节点没有
C正确:正确,参加二叉树性质
D正确:二叉链一般指孩子表示法,三叉连指孩子双亲表示法,这两种方式是二叉树最常见的表示方式,虽然还有孩子兄弟表示法,该中表示方式本质也是二叉链。

  1. 设根结点的深度为1,则一个拥有n个结点的二叉树的深度一定在(A)区间内
    A.[log(n + 1),n]
    B.[logn,n]
    C.[log(n + 1),n - 1]
    D.[log(n + 1),n + 1]

解析: 最大深度: 即每次只有一个节点,次数二叉树的高度为n,为最高的高度。最小深度: 此树为完全二叉树, 如果是完全二叉树。根据二叉树性质,完全二叉树的高低为 h = log(n+1)向上取整。

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

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

相关文章

AIGC知识速递——Google的Bert模型是如何fine-tuning的?

Look!👀我们的大模型商业化落地产品📖更多AI资讯请👉🏾关注Free三天集训营助教在线为您火热答疑👩🏼‍🏫 选择合适的预训练模型: 从预训练的BERT模型开始,例如…

解决PyCharm的Terminal终端conda环境默认为base无法切换的问题

问题描述 在使用PyCharm的Terminal终端时,打开的默认环境为base。 在使用切换命令时,依旧无法解决。 解决方法 1、输入以下命令以查看conda的配置信息: conda config --show2、在输出中找到 auto_activate_base 的行,发现被…

【Linux 基础】常用基础指令(上)

文章目录 一、 创建新用户并设置密码二、ls指令ls指令基本概念ls指令的简写操作 三、pwd指令四、cd指令五、touch指令六、rm指令七、mkdir指令八、rmdir 指令 一、 创建新用户并设置密码 ls /home —— 查看存在多少用户 whoami —— 查看当前用户名 adduser 用户名 —— 创建新…

防御保护--第一次实验

目录 一,vlan的划分及在防火墙上创建单臂路由 二,创建安全区域 三,配置安全策略 四,配置认证策略 五,配置NAT策略 1.将内网中各个接口能够ping通自己的网关 2..生产区在工作时间内可以访问服务器区,仅…

解密人工智能:探索机器学习奥秘

🌈个人主页:聆风吟 🔥系列专栏:网络奇遇记、数据结构 🔖少年有梦不应止于心动,更要付诸行动。 文章目录 📋前言一. 机器学习的定义二. 机器学习的发展历程三. 机器学习的原理四. 机器学习的分类…

探索Pyecharts之美-绘制多彩旭日图的艺术与技巧【第37篇—python:旭日图】

文章目录 引言准备工作绘制基本旭日图调整颜色和样式添加交互功能定制标签和标签格式嵌套层级数据高级样式与自定义进阶主题:动态旭日图数据源扩展:外部JSON文件总结 引言 数据可视化在现代编程中扮演着重要的角色,而Pyecharts是Python中一个…

算法学习之位运算

一、作用 在复杂问题中经常可以作为工具让代码更加优雅。 二、知识储备基础 “~”:取反符 0->1, 1->0 三、常见的两种操作 1.n的二进制表示中第k位数字是几? (1)原理 先右移操作,再与操作。 (2)代码实现…

【C++杂货铺】详解类和对象 [上]

博主:代码菌-CSDN博客 专栏:C杂货铺_代码菌的博客-CSDN博客 目录 🌈前言🌈 📁 面向对象语言的特性 📁 类 📂 概念 📂 定义 📁 访问限定符 📂分类 &#x…

第5章 (python深度学习——波斯美女)

第5章 深度学习用于计算机视觉 本章包括以下内容: 理解卷积神经网络(convnet) 使用数据增强来降低过拟合 使用预训练的卷积神经网络进行特征提取 微调预训练的卷积神经网络 将卷积神经网络学到的内容及其如何做出分类决策可视化 本章将…

线性代数--------学习总结

高斯消去法:对于任意的矩阵,总是能够利用倍加和行变换的方法变化成为阶梯形矩阵(每一行第一个非零元叫做主元,他所在的列就叫做主列------每一行的主列都在他上方任意一行主列的右边)和行简化阶梯矩阵(主元…

C++ STL中list迭代器的实现

list 的模拟实现中,重难点在于迭代器功能的实现,因此本文只围绕 iterator 及 const_iterator 的设计进行介绍,其余如增删查改则不再赘述——在C语言的基础上,这些都非常简单。 与 string / vector 不同,list 的节点原生…

27移除元素(简单)-经典面试150题

题目描述 给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。 不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。 元素的顺序可以改变。你不需要考虑数组中超出…

【高效开发工具系列】Java读取Html

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

计算机考试-软件设计师

文章目录 基础知识分析与设计结构化方法分析与设计基础知识实战法宝 数据库分析与设计基础知识实战法宝 真题练习09下-结构化分析09上-数据库分析 基础知识 分析与设计 整体分析: 1-4分值 15 或者 20 总分55 分 5-6 选做一题 15 总时间150分钟第一题 15分 15分…

【MAC】Multi-Level Monte Carlo Actor-Critic阅读笔记

基本思想: 利用多层次蒙特卡洛方法(Multi-Level Monte Carlo,MLMC)和Actor-Critic算法,解决平均奖励强化学习中的快速混合问题。 快速混合? 在强化学习中,当我们说一个策略"混合得快"…

绘制太极图 - 使用 PyQt

大家好!今天我们将一起来探讨一下如何使用PyQt,这是一个强大的Python库,来绘制一个传统的太极图。这个图案代表着古老的阴阳哲学,而我们的代码将以大白话的方式向你揭示它的奥秘。 PyQt:是什么鬼? 首先&a…

Python爬虫---Scrapy框架---CrawlSpider

CrawlSpider 1. CrawlSpider继承自scrapy.Spider 2. CrawlSpider可以定义规则,再解析html内容的时候,可以根据链接规则提取出指定的链接,然后再向这些链接发送请求,所以,如果有需要跟进链接的需求,意思就是…

hardware simulation——编译框架优化

目录 介绍 修改前的最新代码和框架 学习和修改 最终版本 介绍 -------------------------------------------------------------------------------------------------------------------------- https://www.cnblogs.com/wittxie/p/9836097.html 上次那个虽然能完成基本…

计算方法实验2:利用二分法及不动点迭代求解非线性方程

一、问题描述 利用二分法及不动点迭代求解非线性方程。 二、实验目的 掌握二分法及不动点迭代的算法原理;能分析两种方法的收敛性;能熟练编写代码实现利用二分法及不动点迭代来求解非线性方程。 三、实验内容及要求 二分法 (1) 编写代码计算下列数字…

STM正点mini-新建工程模板,GPIO及寄存器(介绍)

一.新建工程模板(基于固件库) 1.1库函数与寄存器的区别 这里的启动文件都是根据容量来进行区分的 对MDK而言即使include了,也不知道在哪里找头文件 STM32F10X_HD,USE_STDPERIPH_DRIVER 二.新建工程模板(基于寄存器) 上面的大部分配置与固件库的一样 具体可以看手…