【数据结构与算法】二叉树基础OJ -- 上 (巩固提高)

news2024/11/29 8:54:00

前言:

💥🎈个人主页:​​​​​​Dream_Chaser~ 🎈💥

✨✨刷题专栏:http://t.csdn.cn/UlvTc

⛳⛳本篇内容:力扣上二叉树OJ基础练习

​​​​​​​

目录

leetcode 965.单值二叉树

题目描述:

解题思路:

leetcode 100.相同的树

题目描述:

解题思路:

leetcode 101.对称二叉树

题目描述:

解题思路:

leetcode 144.二叉树的前序遍历(需要数组存储)

题目描述:

解题思路:

leetcode 572.另一棵树的子树

题目描述:

解题思路:


leetcode 965.单值二叉树

题目来源:965. 单值二叉树 - 力扣(LeetCode)

题目描述:

如果二叉树每个节点都具有相同的值,那么该二叉树就是单值二叉树

只有给定的树是单值二叉树时,才返回 true;否则返回 false

示例 :

解题思路:

        a == b b == c  推论: a == c,利用了值的传递性,根与子树也是可以利用这一性质解题。

        1.开始的时候先判断这棵树是否为空,假设是空,那么直接返回true,因为NULL也可以是这棵树唯一的一个值。

       

         2.接着若根节点不为空,那么这时候先访问根的左子树root->left,让其作为if的判断条件(判断左子树是否为空),然后用&&连接起另一个判断条件:root->left->val != root->val 也就是访问左子树的val与其根节点的val是否不相等,

        这里着重说明一下:root->val 如果等于root->left->val是说明不了问题的,因为相等了还是要找下一个节点判断与其根节点什么关系,这属于是不确定的条件,

        所以要找确定的条件:直接让root->left->val != root->val,如果条件成立则直接返回false.

右子树同理.

       

        3.如果根节点与子树相等,那么就直接让isUnivalTree(root->left) && isUnivalTree(root->right)作为返回条件.

        用&&的原因就是有其中一棵子树值不全相等,那么说明该树不是单值,返回false

图解:

代码实现:

bool isUnivalTree(struct TreeNode* root){
    if(root == NULL)
        return true;
    
    if(root->left && root->left->val != root->val)
        return false;

    if(root->right && root->right->val != root->val)
        return false;

    return isUnivalTree(root->left)&&isUnivalTree(root->right);
}

执行:

leetcode 100.相同的树

题目来源:100. 相同的树 - 力扣(LeetCode)

题目描述:

给你两棵二叉树的根节点 p 和 q ,编写一个函数来检验这两棵树是否相同。

如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。

示例:

解题思路:

  1. 首先检查两棵树是否都为空。如果是,则它们具有相同的值,返回true
  2. 如果两棵树中有一棵为空而另一棵不为空,则它们不相等,返回false
  3. 如果两棵树的当前节点的值不相等,则它们不相等,返回false
  4. 如果以上情况都不满足,即两棵树的当前节点的值相等,则递归地调用isSameTree函数,传入左子树,并进行相同的比较。
  5. 同样地,递归地调用isSameTree函数,传入右子树,并进行相同的比较。
  6. 如果左右子树的比较结果都为true,则说明两棵树相等,返回true;否则返回false

图解:图上数字代表遍历顺序,说明两子树是同时进行的。

 代码实现:

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);
}

执行:

leetcode 101.对称二叉树

题目来源:101. 对称二叉树 - 力扣(LeetCode)

题目描述:

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

示例:

解题思路:

         首先,因为oj里面的原函数满足不了我们在一颗树内同时操作左右子树的需求,因为只有一个指针,操作不了左右两个方向。(记住原函数包括函数名、返回条件、参数都是不能改变的)

        这时候我们定义一个函数is_Symmetrict(root->left,root->right),接着传入指针,然后可以同时开始操作,左右子树。

        1.先判断左右子树是否为空,因为地址为空在结构上也是对称的一个结果,然后返回true

        2. 判断以下子树一个为空,另一个是否也为空,两者同时为空则返回false,

        3、两子树不为空但不相等,返回false。

        若上述条件均不满足,即左子树和右子树都不为空,且它们的根节点的值相等,那么继续递归地调用 is_Symmetrict 函数,分别传入左子树的左子树和右子树的右子树,以及左子树的右子树和右子树的左子树。

        如果递归调用的返回值都为 true,则说明左子树和右子树对称,返回 true;否则返回 false

图解:​​​​​​​

代码实现:

bool is_Symmetrict(struct TreeNode*leftroot,struct TreeNode*rightroot)
{
    //找确定的条件
    //左子树右子树两个为空
    if(leftroot==NULL && rightroot == NULL)
        return true;

    //左子树或右子树,一个为空
    if(leftroot == NULL || rightroot == NULL)
        return false;

    if(leftroot->val != rightroot->val)
    return false;

    return is_Symmetrict(leftroot->left , rightroot->right) && 
    is_Symmetrict(leftroot->right , rightroot->left);
}
bool isSymmetric(struct TreeNode* root){
   return is_Symmetrict(root->left,root->right);   
}

执行:

leetcode 144.二叉树的前序遍历(需要数组存储)

题目来源:144. 二叉树的前序遍历 - 力扣(LeetCode)

题目描述:

给你二叉树的根节点 root ,返回它节点值的 前序 遍历。

示例:

 解题思路:

        首先用TreeSize函数算出二叉树的节点数量,具体实现看这篇文章:http://t.csdnimg.cn/DvuEU

       接着用*returnsize这个值接收,为什么要解引用?因为传过来的是size的地址-->&size

图解在这:实现其main函数:

         接着malloc一块空间,定义指针int*a指向,定义变量i,接着传入preorder函数,进行前序遍历,之后返回a的地址。

代码实现:

int TreeSize(struct TreeNode* root)
{
    return root == NULL ? 0:TreeSize(root->left) + TreeSize(root->right)+1; 
}
void preorder(struct TreeNode*root,int*a,int*i)
{
    if(root==NULL)
    {
        return ;
    }
    a[(*i)++]=root->val;
    preorder(root->left,a,i);
    preorder(root->right,a,i);
}
int* preorderTraversal(struct TreeNode* root, int* returnSize)
{
    *returnSize = TreeSize(root);
    int* a= malloc(*returnSize*sizeof(struct TreeNode));

    int i=0;
    preorder(root,a,&i);
    return a;
}

执行:

关于此题有两个疑问:

        1.用局部变量,下面的这个代码可以吗?

int TreeSize(struct TreeNode* root)
{
    return root == NULL ? 0:TreeSize(root->left) + TreeSize(root->right)+1; 
}
void _preorder(struct TreeNode* root, int* a,int i)
{
	if (root == NULL)
		return;
	//用指针的方式是为了不在不同栈帧内创建i
	a[i++] = root->val;
	_preorder(root->left, a,i);
	_preorder(root->right, a,i);
}

int* preorderTraversal(struct TreeNode* root, int* returnSize)
{
	*returnSize = TreeSize(root);
	int* a = (int*)malloc(*returnSize * sizeof(int));

	int i = 0;
	_preorder(root,a,i);
	return a;
}

结果是不行,为什么?用局部变量就不行吗? 

以下是我的理解: 

 2.全局变量可以吗?

        可以,但是先列举问题:

解析:        

        虽然全局变量 i 在定义时已经被初始化为 0,但是全局变量的赋值操作只会在程序启动时执行一次。每次调用 _preorder 函数时,由于没有显式地给 i 赋新的值,i 的值会保持上一次调用结束时的值。这样会导致多次调用 _preorder 函数时,节点值被存储在错误的位置,结果可能不符合预期。

        因此,在函数内部显式地给 i 赋值为 0,可以确保每次调用 _preorder 函数时都从数组 a 的开头位置开始存储节点的值,避免出现错误的索引位置。

leetcode 572.另一棵树的子树

题目来源:572. 另一棵树的子树 - 力扣(LeetCode)

题目描述:

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

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

示例:

解题思路:

  1. 首先,判断 root 是否为 NULL,如果是,则不存在子树,返回 false
  2. 接着,调用 isSameTree 函数,判断 root 和 subRoot 是否相同,如果是,则 subRoot 是 root 的子树,返回 true
  3. 如果以上条件都不满足,递归调用 isSubtree 函数,分别判断 subRoot 是否是 root 的左子树的子树,或者是 root 的右子树的子树。只要有一边存在子树,就返回 true
  4. 如果都不满足,则 subRoot 不是 root 的子树,返回 false

图解:

代码实现:

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);
}

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

代码执行:
​​​​​​​

        本篇文章在这里就结束了,如有需要补充的,欢迎评论! 

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

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

相关文章

pytorch笔记:TRIPLETMARGINLOSS

1 介绍 创建一个衡量三元组损失的标准,给定输入张量 x1​、x2​ 和 x3​ 以及一个大于0的间距值。这用于测量样本之间的相对相似性。一个三元组由a、p和n组成(锚点、正例和负例)。所有输入张量的形状都应为 (N,D) 2 基本使用方法 torch.nn.…

深度学习之基于YoloV8的行人跌倒目标检测系统

欢迎大家点赞、收藏、关注、评论啦 ,由于篇幅有限,只展示了部分核心代码。 文章目录 一项目简介 二、功能三、行人跌倒目标检测系统四. 总结 一项目简介 世界老龄化趋势日益严重,现代化的生活习惯又使得大多数老人独居,统计数据表…

前端 : 用HTML ,CSS ,JS 做一个点名器

1.HTML&#xff1a; <body><div id "content"><div id"top"><div id "name">XAiot2302班点名器</div></div><div id "center"><div id "word">你准备好了吗?</di…

IOC课程整理-7 Spring IoC 依赖来源

1 依赖查找的来源 2 依赖注入的来源 3 Spring容器管理和游离对象 4 Spring BeanDefinition 作为依赖来源 5 单例对象作为依赖来源 7 非 Spring 容器管理对象作为依赖来源 8 外部化配置作为依赖来源 面试题 1 注入和查找的依赖来源是否相同 &#xff1a;否&#xff0c;依赖查…

Ps:对象选择工具

对象选择工具 Object Selection Tool是 Photoshop 2020 版以后新增的选区工具&#xff0c;可用于自动选择图像中的对象或区域&#xff0c;如人物、汽车、宠物、天空、水、建筑物和山脉等。 快捷键&#xff1a;W 让对象选择工具自动检测并选择图像内的对象或区域&#xff0c;或者…

问题 Q: 小希的迷宫(并查集+最小生成树)

注意点一&#xff1a;在一个循环读入数据&#xff09; 1.读到0 0 则&#xff0c;输入判断&#xff0c;然后下组数据 &#xff08;因为房间编号最小为1&#xff0c;不存在0 0 接-1 -1的情况&#xff09; 2.读到-1 -1 则 结束 注意点二&#xff1a;判断数据老大是否重复 注意点…

GLoRE:大型语言模型的逻辑推理能力探究

最新研究揭示&#xff0c;尽管大语言模型LLMs在语言理解上表现出色&#xff0c;但在逻辑推理方面仍有待提高。为此&#xff0c;研究者们推出了GLoRE&#xff0c;一个全新的逻辑推理评估基准&#xff0c;包含12个数据集&#xff0c;覆盖三大任务类型。 实验对比发现&#xff0c;…

记一次线程爆满导致服务器崩溃的问题排查

记一次线程爆满导致服务器崩溃的问题排查 重启服务器 重启后&#xff0c;ssh连接发现下面问题 fork faild:Cannot allocate memory 以为是内存满了 于是&#xff0c;free -h,查看内存情况&#xff0c;还有&#xff0c;观察一段时间后&#xff0c;内存没多大变化 修改…

网络协议--TCP的交互数据流

19.1 引言 前一章我们介绍了TCP连接的建立与释放&#xff0c;现在来介绍使用TCP进行数据传输的有关问题。 一些有关TCP通信量的研究如[Caceres et al. 1991]发现&#xff0c;如果按照分组数量计算&#xff0c;约有一半的TCP报文段包含成块数据&#xff08;如FTP、电子邮件和U…

python爬虫之feapder.AirSpider轻量爬虫案例:豆瓣

创建feaderSpider项目&#xff1a;feapder create -p feapderSpider&#xff0c;已创建可忽略进入feapderSpider目录&#xff1a;cd .\ feapderSpider\spiders创建爬虫&#xff1a;feapder create -s airSpiderDouban&#xff0c;选择AirSpider爬虫模板&#xff0c;可跳过1、2直…

Java集合类--List集合,Set集合,Map集合

集合可以看作一个容器&#xff0c;Java中提供了不同的集合类&#xff0c;这些类具有不同的存储对象的方式&#xff0c;同时提供了相应的方法&#xff0c;以便用户对集合进行遍历、添加、删除、查找指定的对象。 1.集合类概述&#xff1a; 集合类类似于数组&#xff0c;与数组不…

即时编译器JIT

类编译加载执行过程 如下图所示&#xff0c;一个Java代码从编译到运行大抵会经历以下几个过程。具体每个过程笔者会在下文站展开讨论。 类编译 首先是类编译阶段&#xff0c;这个阶段会将Java文件变为class文件&#xff0c;这个class文件包含一个常量池和方法表集合&#xf…

2023年第四届MathorCup高校数学建模挑战赛——大数据竞赛B题解题思路

比赛时长为期7天的妈杯大数据挑战赛如期开赛&#xff0c;为了帮助对B题有更深的理解&#xff0c;这里为大家带来B题的初步解题思路。 赛道B&#xff1a;电商零售商家需求预测及库存优化问题 由于妈杯竞赛分为初赛复赛&#xff0c;因此&#xff0c;对于B题大家仅仅看到了预测相…

nodejs+vue+elementui社区居民信息管理及数据分析与可视化系统设计

其中用户登录中&#xff0c;通过HTML访问该社区居民信息管理及数据分析与可视化系统&#xff0c;选择登录界面&#xff0c;进行登录。登录成功进入到系统&#xff0c;登录失败&#xff0c;提示用户不存在&#xff0c; 流入人口管理中&#xff0c;启动社区居民信息管理及数据分…

C语言二、八、十六进制转换

二进制转八进制、十六进制 二进制转八进制&#xff1a; 三合一法&#xff1a; 从低位到高位&#xff0c;每 3 给二进制组成 1 位八进制数据&#xff0c;高位不够三位用 0 填补&#xff0c;将二进制转为对应的八进制数即可 二进制转十六进制&#xff1a; 四合一法&#xff1a;…

基于nodejs+vue食力派网上订餐系统

目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪论 1 1.1背景及意义 1 1.2 国内外研究概况 1 1.3 研究的内容 1 第2章 相关技术 3 2.1 nodejs简介 4 2.2 express框架介绍 6 2.4 MySQL数据库 4 第3章 系统分析 5 3.1 需求分析 5 3.2 系统可行性分析 5 3.2.1技术可行性&#xff1a;…

git学习笔记-发现问题如何恢复

1.概要 git总出各种问题&#xff0c;不清楚原因。所以准备了解的跟深入些。本来的理解是这样的: 下载我就pull 修改完就 commit然后push 怎么会有问题的&#xff0c;结果还总有。 既然问题无法避免&#xff0c;那就提高解决问题和恢复问题的能力。如果问题能够恢复就没有什…

lesson2(补充)取地址及const取地址操作符重载

个人主页&#xff1a;Lei宝啊 愿所有美好如期而遇 以下两个默认成员函数一般不用重新定义 &#xff0c;编译器默认会生成。 #include <iostream> using namespace std;class Date {public:Date():_year(2023),_month(10),_day(28){}Date* operator&(){return this…

RabbitMQ学习01

四大核心概念 生产者 产生数据发送消息的程序是生产者 交换机 交换机是 RabbitMQ 非常重要的一个部件&#xff0c;一方面它接收来自生产者的消息&#xff0c;另一方面它将消息推送到队列中。交换机必须确切知道如何处理它接收到的消息&#xff0c;是将这些消息推送到特定队…

内网穿透工具之NATAPP(一)

使用工具前&#xff0c;有必要了解一下什么是内网穿透吧&#xff01; 内网穿透简单来说就是将内网外网通过natapp隧道打通,让内网的数据让外网可以获取。比如常用的办公室软件等&#xff0c;一般在办公室或家里&#xff0c;通过拨号上网&#xff0c;这样办公软件只有在本地的局…