【刷题大本营】二叉树进阶oj题(动图讲解,附代码及题目链接)

news2025/1/12 17:31:58

       🔥🔥 欢迎来到小林的博客!!
      🛰️博客主页:✈️小林爱敲代码
      🛰️欢迎关注:👍点赞🙌收藏✍️留言
首页图片

      这篇文章给大家带来一些关于二叉树的oj题



         每日一句: 立身以立学为先,立学以读书为本。

目录

  • 💖1. 二叉树的分层遍历
  • 💖2. 二叉树的分层遍历(逆)
  • 💖3. 找2个节点的最近公共祖先
  • 💖4. 二叉搜索树与双向链表
  • 💖5. 从前序与中序遍历序列构造二叉树
  • 💖6.从中序与后序遍历序列构造二叉树
  • 总结🥳:

💖1. 二叉树的分层遍历

题目:

在这里插入图片描述
解题思路:
用一个队列入数据,并且用一个变量leavesSize 来记录当前一层的数据个数。然后用数组存储当前这一层的数据。再把这个数组添加到数组中。
在这里插入图片描述

代码:

    vector<vector<int>> levelOrder(TreeNode* root) {
        queue<TreeNode*> q;
        vector<vector<int>> vv;
        int leavesSiez = 1;
        //入根节点,根节点为空说明是空树
        if(root)
            q.push(root);

        //队列为空结束循环
        while(!q.empty())
        {
            vector<int> v;
            while(leavesSiez--)
            {
                TreeNode* front = q.front();
                //放进数组
                v.push_back(front->val);
                //弹出队头数据
                q.pop();
                //左右子树不为空则入队列
                if(front->left)
                    q.push(front->left);
                if(front->right)
                    q.push(front->right);
            }
            //更新层数节点数量
            leavesSiez = q.size();
            vv.push_back(v);
        }
        return vv;
    }

题目链接:https://leetcode.cn/problems/binary-tree-level-order-traversal/submissions/


💖2. 二叉树的分层遍历(逆)

题目:
在这里插入图片描述
思路: 和上一题一样,只不过把最后返回的数组逆置即可。
代码:

    vector<vector<int>> levelOrder(TreeNode* root) {
        queue<TreeNode*> q;
        vector<vector<int>> vv;
        int leavesSiez = 1;
        //入根节点,根节点为空说明是空树
        if(root)
            q.push(root);

        //队列为空结束循环
        while(!q.empty())
        {
            vector<int> v;
            while(leavesSiez--)
            {
                TreeNode* front = q.front();
                //放进数组
                v.push_back(front->val);
                //弹出队头数据
                q.pop();
                //左右子树不为空则入队列
                if(front->left)
                    q.push(front->left);
                if(front->right)
                    q.push(front->right);
            }
            //更新层数节点数量
            leavesSiez = q.size();
            vv.push_back(v);
        }
        //数组逆置
        reverse(vv.begin(),vv.end());
        return vv;
    }

题目链接:https://leetcode.cn/problems/binary-tree-level-order-traversal-ii/

💖3. 找2个节点的最近公共祖先

题目:
在这里插入图片描述
解题思路:用两个栈来保存2个节点的路径。随后会产生一大一小的两个栈,使大的栈和小的栈一样大后,同时pop比较节点地址。
我们可以分次查找,第一次找p的地址,第二次找q的地址。而查找的时候,一进去就让数据入栈,随后把该节点看成一棵树,如果这棵树里面没有找到要查找的节点,那么就会pop掉入栈的数据。如果找到了,返回true。
假设我们要找 6和7的最近公共父节点。
在这里插入图片描述
第一次查找,先遍历二叉树,去查找6的节点
在这里插入图片描述
第二次查找,遍历二叉树,查找7的节点。
在这里插入图片描述
随后我们得到了stack1和stack2两个栈,那么我们让长度长的那个栈pop,直到pop到两个栈一样大时,再同时pop。
在这里插入图片描述
2个栈栈顶节点相等时,随便返回一个即可。

代码:

 bool FindNode(TreeNode* root,TreeNode* x,stack<TreeNode*>& stack)
    {
        //如果root为空,说明没找到,返回flase
        if(root == nullptr)
            return false;
        //节点入栈,保存路径
        stack.push(root);

        //如果找到了,返回true
        if(root == x)
            return true;

        //递归找左子树,如果有返回true的,说明找到了,就返回true,没找到则继续找右子树
        if(FindNode(root->left,x,stack))
            return true;
        //递归找右子树
        if(FindNode(root->right,x,stack))
            return true;
        
        //左右子树都没找到,说明这棵树没有要找的节点,那么pop掉刚开始push进来的根节点
        stack.pop();
        return false;
    }

    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        stack<TreeNode*> stack1;
        stack<TreeNode*> stack2;
        //找p节点
        FindNode(root,p,stack1);
        //找q节点
        FindNode(root,q,stack2);
            
        //使两个栈长度一样
        while(stack1.size() != stack2.size())
        {
            if(stack1.size() > stack2.size())
                stack1.pop();
            else
                stack2.pop();
        }
        //到这里两个栈一样大了,那么同时出数据
        while(stack1.top() != stack2.top())
        {
            stack1.pop();
            stack2.pop();
        }

        //随便返回一个
        return stack1.top();
    }

题目链接:https://leetcode.cn/problems/lowest-common-ancestor-of-a-binary-tree/submissions/

💖4. 二叉搜索树与双向链表

题目描述:
在这里插入图片描述

解题思路:首先,这个二叉树是被中序遍历的。而在遍历的过程中,我们需要保存前一个节点。这样才能相互链接。
在这里插入图片描述
如图所示,按照图中步骤,即可实现链接过程。

代码:

	void InOrder(TreeNode* cru,TreeNode*& prev)
	{
		//中序遍历
		if(cru == nullptr)
			return;
		InOrder(cru->left,prev);

		//链接操作
		cru->left = prev;
		if(prev)
			prev->right = cru;
		//prev到cru的位置上
		prev = cru;
		InOrder(cru->right,prev);
	}

	TreeNode* Convert(TreeNode* pRootOfTree) {
		TreeNode* prve = nullptr;
		InOrder(pRootOfTree,prve);
		TreeNode* head = pRootOfTree;
		//找链表头节点
		while(head && head->left)
		{
			head = head->left;
		}
		return head;
	}

题目链接:https://www.nowcoder.com/practice/947f6eb80d944a84850b0538bf0ec3a5?tpId=13&&tqId=11179&rp=1&ru=/activity/oj&qru=/ta/coding-interviews/question-ranking

💖5. 从前序与中序遍历序列构造二叉树

题目:
在这里插入图片描述
解题思路:用begini 和 endi 变量作为一颗树的区间,而prei则是树的根节点,因为是前序遍历。所以我们在前序数组中找根,在中序数组里找根的子树区间。
在这里插入图片描述

代码:

 TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
       int prei = 0;
       return _buildTree(preorder,inorder,prei,0,inorder.size()-1);
    }

    TreeNode* _buildTree(vector<int>& preorder, vector<int>& inorder,int& prei,int begini,int endi) {
        //如果begin大于endi,说明没有节点了。
        if(begini > endi)
            return nullptr;
        //创建根节点
         TreeNode* root = new  TreeNode(preorder[prei]);
        //找到根节点在中序数组里的下标
        int rooti = 0;
        while(inorder[rooti] != root->val )
        {
            rooti++;
        }
        //prei++代表下一颗树的根,也代表这棵树的节点
        prei++;
        //begini - rooti -1 是root的左树区间,rooti+1 - endi是root的右树区间
        root->left = _buildTree(preorder,inorder,prei,begini,rooti-1);
        root->right = _buildTree(preorder,inorder,prei,rooti+1,endi);
        return root;
    }

题目链接:https://leetcode.cn/problems/construct-binary-tree-from-preorder-and-inorder-traversal/submissions/

💖6.从中序与后序遍历序列构造二叉树

题目:
在这里插入图片描述

解题思路:
中序与后序构造前序二叉树,和前序与中旬构造后序二叉树差不多。思想都是一致的,有3个变量,posti控制树的根,begini和endi控制树的区间。前序数组的第一个元素就是树的根,那么后序数组的最后一个元素就是它的根。从后往前需要注意点的就是,必须要先连接右树,再连左树,否则posti的值会对不上。
在这里插入图片描述

代码:

    TreeNode* _buildTree(vector<int>& inorder, vector<int>& postorder,int& posti,int begini,int endi) {
        //左区间比右区间大, 说明没有节点了
        if(begini > endi)
            return nullptr;
        //创建根节点
        TreeNode* root = new TreeNode(postorder[posti]);
        int rooti = 0 ;
        //找到根节点在中序数组的下标
        while(inorder[rooti] != root->val)
        {
            rooti++;
        }
        posti--;
        //先链接右节点,后序遍历是左,右,根。反过来就是 根 右 左
        root->right = _buildTree(inorder,postorder,posti,rooti+1,endi);
        root->left = _buildTree(inorder,postorder,posti,begini,rooti-1);
        return root;
    }
    
    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
        int posti = postorder.size() - 1;
        return _buildTree(inorder,postorder,posti,0, postorder.size() - 1);
    }

题目链接:https://leetcode.cn/problems/construct-binary-tree-from-inorder-and-postorder-traversal/

总结🥳:

💦💦如果有写的有什么不好的地方,希望大家指证出来,我会不断的改正自己的错误。💯💯如果感觉写的还可以,可以点赞三连一波哦~🍸🍸后续会持续为大家更新.

🔥🔥你们的支持是我最大的动力,希望在往后的日子里,我们大家一起进步!!!
🔥🔥

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

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

相关文章

RK3399平台开发系列讲解(文件系统篇)文件回写过程介绍

🚀返回专栏总目录 文章目录 一、编程接口二、回写过程2.1、周期回写2.2、强制回写2.3、系统调用sync沉淀、分享、成长,让自己和他人都能有所收获!😄 📢进程写文件时,内核的文件系统模块把数据写到文件的页缓存,没有立即写回到存储设备。文件系统模块会定期把脏页(即…

[JavaEE]线程池

专栏简介: JavaEE从入门到进阶 题目来源: leetcode,牛客,剑指offer. 创作目标: 记录学习JavaEE学习历程 希望在提升自己的同时,帮助他人,,与大家一起共同进步,互相成长. 学历代表过去,能力代表现在,学习能力代表未来! 目录: 1. 线程池是什么? 2. 线程池的实现原理 3. 标准…

Eureka集群构建步骤

目录 一、Eureka集群原理说明 二、EurekaServer集群环境构建步骤 三、将支付服务8001微服务发布到上面2台Eureka集群配置中 四、将订单服务80微服务发布到上面2台Eureka集群配置中 五、测试01 六、支付服务提供者8001集群环境构建 七、负载均衡 八、测试02 一、Eureka集…

论文投稿指南——中文核心期刊推荐(建筑科学)

【前言】 &#x1f680; 想发论文怎么办&#xff1f;手把手教你论文如何投稿&#xff01;那么&#xff0c;首先要搞懂投稿目标——论文期刊 &#x1f384; 在期刊论文的分布中&#xff0c;存在一种普遍现象&#xff1a;即对于某一特定的学科或专业来说&#xff0c;少数期刊所含…

前同事居然因为 Pycharm 的这个功能,即使离职三年也依然经常被请去喝茶~

大家好&#xff0c;我是 哈士奇 &#xff0c;一位工作了十年的"技术混子"&#xff0c; 致力于为开发者赋能的UP主, 目前正在运营着 TFS_CLUB社区。 &#x1f4ac; 人生格言&#xff1a;优于别人,并不高贵,真正的高贵应该是优于过去的自己。&#x1f4ac; &#x1f4e…

教你一键生成形如Springboot的高大上banner打印效果

背景 今天闲来无聊&#xff0c;想搞一个类似于Springboot项目启动时打印效果&#xff0c;如下图&#xff1a; 问题解决方案 那这个打印效果怎么实现的呢&#xff1f; 其实&#xff0c;对于这个中效果实现起来也是很简单的。毕竟依托于Springboot强大的框架&#xff0c;任何问…

网狐大联盟非联盟成员无法创建房间解决-暂时不可创建当前游戏,请选择其他游戏!

"暂时不可创建当前游戏,请选择其他游戏!" 问题所有lua文件定位:

恶意代码分析实战 16 Shellcode分析

16.1 Lab19-01 将程序载入IDA。 一堆ecx自增的操作。到200是正常的代码段。 shellcode的解码器也是从这里开始的&#xff0c;一开始的xor用于清空ecx&#xff0c;之后将18dh赋给cx&#xff0c;jmp来到loc_21f,而在下图可以看到loc_21调用sub_208,在call指令执行后&#xff0…

40.Isaac教程--3D 物体姿态优化

3D 物体姿态优化 ISAAC教程合集地址: https://blog.csdn.net/kunhe0512/category_12163211.html 3D 物体姿态优化在操作等应用中起着至关重要的作用&#xff0c;在这些应用中&#xff0c;检测到的物体的位置会影响机器人的整体性能。 Isaac SDK 中的 3D 对象姿势优化应用程序提…

7. 好客租房-项目日常推进ing

7. 好客租房-项目日常推进ing 本章节不涉及大量内容,主要是为了推荐项目代码日常进度而设置, 包括添加mock接口, 添加更新房源接口, 为系统添加缓存. 7.1 为前端系统提供mock服务 往往在项目开发中, 为实现前后端并行开发&#xff0c;后端需要对前端所有的请求都都进行支持。…

2022年度总结——2022我在CSDN的那些事暨2023我的目标展望:Pursue freedom Realize self-worth

&#x1f4cb;前言 关于年度征文&#xff1a; 活动地址&#xff1a;2022年度征文活动页-CSDN &#x1f4da;文章目录 &#x1f4cb;前言 &#x1f3af;再见2022&#xff0c;2023新年快乐 &#x1f3af;回顾2022——“我”与我在CSDN的那些事 &#x1f9e9;伊始——CSDN&…

Allegro如何做镂空丝印操作指导

Allegro如何做镂空丝印操作指导 在PCB设计丝印的时候,会需要画镂空的丝印,Allegro升级到了172版本的时候,可以画镂空的丝印,如下图 具体操作如下 选择Shape Add Rect命令Options选择需要画到的层面,比如Silkscreen TOP层

Lesson1:走进C++的殿堂

首先在此声明一下&#xff0c;C的学习需要C语言的基础&#xff0c;不先学习C语言而直接学C是不现实的。市面上任何一本C的书籍&#xff0c;前几章的内容一定涉及到C语言的学习。 一、什么是C 照片上的这位老人便是C语言之父——本贾尼斯特劳斯特卢普&#xff08;Bjarne Stroust…

JavaScript学习

JavaScript 是一门跨平台、面向对象的脚本语言&#xff0c;而Java语言也是跨平台的、面向对象的语言&#xff0c;只不过Java是编译语言&#xff0c;是需要编译成字节码文件才能运行的&#xff1b;JavaScript是脚本语言&#xff0c;不需要编译&#xff0c;由浏览器直接解析并执行…

Spring核心模块解析—BeanDifinition。

BeanDifinition前言什么是BeanDefinition&#xff1f;为什么要有BeanDefinition&#xff1f;BeanDifinition重点源码总结前言 Spring中的BeanDifinition在Bean的实例化流程中占有着非常重要的角色&#xff0c;如果你不了解BeanDifinition的话&#xff0c;面试或者学习Bean的生…

【Leetcode每日一题】69. x 的平方根/Sqrt(x)|二分查找---day3

博主简介&#xff1a;努力学习的预备程序媛一枚~博主主页&#xff1a; 是瑶瑶子啦所属专栏: LeetCode每日一题–进击大厂 目录题目描述题目分析&#xff1a;代码分析&#xff1a;题目描述 链接: 69. x 的平方根/Sqrt(x) 给你一个非负整数 x &#xff0c;计算并返回 x 的 算术…

10+种编程语言做个计算器

用十种编程语言开发计算器应用 C语言C#&#xff08;windows桌面软件&#xff09;Swift &#xff08;ios应用&#xff09;pythonDart&#xff08;Flutter应用&#xff0c;跨平台&#xff0c;适用安卓、ios、mac、windows、web&#xff09;Java&#xff08;安卓App&#xff09;K…

【Linux】多线程同步与互斥

目录&#x1f308;前言&#x1f338;1、Linux线程同步&#x1f368;1.1、同步概念与竞态条件&#x1f367;1.2、条件变量&#x1f33a;2、条件变量相关API&#x1f368;2.1、初始化和销毁条件变量&#x1f367;2.2、阻塞等待条件满足&#x1f383;2.3、唤醒阻塞等待的条件变量&…

python数据可视化开发:Matplotlib库参数配置基础知识

文章目录前言01.工具栏组件02.数据03.设置字体字典&#xff08;1&#xff09;全局字体样式&#xff08;2&#xff09;常用中文字体对应名称&#xff08;3&#xff09;查询当前系统所有字体04.图像配置实例05.图表标题06.文本组件07.坐标轴标签组件08.网格组件09.绘制折线10.图例…

传染疾病模型

1 分支过程 1.1 工作原理 第一波疫情 假设一个人携带一种新的病毒&#xff0c;以独立的概率p将疾病传染给遇到的每一个人假设这个人在感染期遇到了k个人 ——>这k个人是该疾病传染的第一波基于疾病是随机传染的&#xff0c;所以第一波中有些人会感染疾病&#xff0c;有些人…