【Leetcode】二叉树进阶面试题

文章目录

  • 二叉树创建字符串
  • 二叉树分层遍历(从前开始)
  • 二叉树分层遍历(从后开始)
  • 二叉树的最近公共祖先
  • 二叉搜索树与双向链表
  • 从前序与中序遍历序列构造二叉树
  • 从中序与后序遍历序列构造二叉树
  • 二叉树的前序遍历(非递归)
  • 二叉树的中序遍历(非递归)
  • 二叉树的后续遍历

二叉树创建字符串

在这里插入图片描述
在这里插入图片描述

思路: 该题需要注意的细节就是当节点的左子树为空,而右子树却不为空的情况,就需要特殊处理,也是需要加上(),而节点的左子树不为空,右子树为空就是不需要加上()if(root->left||root->right)该语句就是实现左子树的字符和(),之后再去处理右子树。

//C++
class Solution {
public:string tree2str(TreeNode* root) {if(root==nullptr){return "";}string str=to_string(root->val);if(root->left||root->right){str+='(';str+=tree2str(root->left);str+=')';}if(root->right){str+='(';str+=tree2str(root->right);str+=')';}return str;}
};

二叉树分层遍历(从前开始)

在这里插入图片描述
在这里插入图片描述

**思路:**创建一个队列,将遍历的数据存入到里面,在创建一个计数器用来记录每层的数据个数。

class Solution {
public:vector<vector<int>> levelOrder(TreeNode* root) {queue<TreeNode*> q;vector<vector<int>> vv; int levelsize=0;if(root){q.push(root);levelsize=1;}while(!q.empty()){vector<int> v;while(levelsize--){TreeNode* front=q.front();q.pop();v.push_back(front->val);if(front->left){q.push(front->left);}if(front->right){q.push(front->right);} }vv.push_back(v);levelsize=q.size();}return vv;}
};

二叉树分层遍历(从后开始)

在这里插入图片描述
在这里插入图片描述

**思路:**其实他就和上一个题的思路是一样的,只需要加个翻转就可以了。

class Solution {
public:vector<vector<int>> levelOrderBottom(TreeNode* root) {queue<TreeNode*> q;vector<vector<int>> vv; int levelsize=0;if(root){q.push(root);levelsize=1;}while(!q.empty()){vector<int> v;while(levelsize--){TreeNode* front=q.front();q.pop();v.push_back(front->val);if(front->left){q.push(front->left);}if(front->right){q.push(front->right);} }vv.push_back(v);levelsize=q.size();}reverse(vv.begin(),vv.end());return vv;}
};

二叉树的最近公共祖先

在这里插入图片描述
在这里插入图片描述

思路:
1、使用三叉链(有父节点)转换为链表相交问题,其中长的一条先走gap。
2、就是进行判断确定一个数在自己的左边,另一个在自己的右边。不在用一边就说明现在的节点就是最近的公共祖先,在同一边就需要继续向下找。

class Solution {
public:bool Isintree(TreeNode* root,TreeNode* in){if(root==nullptr){return false;}if(root==in){return true;}else{return Isintree(root->left,in) || Isintree(root->right,in);}}TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {if(root==nullptr){return nullptr;}if(p==root || q==root){return root;}bool pinleft=Isintree(root->left,p);bool pinright=!pinleft;bool qinleft=Isintree(root->left,q);bool qinright=!qinleft;if((pinleft && qinright) || (pinright && qinleft)){return root;}else if(pinleft&&qinleft){return lowestCommonAncestor(root->left,p,q);}else{return lowestCommonAncestor(root->right,p,q);}}
};

注意: 上面的写法是属于性能较低的,他所用的时间是较长的。时间复杂度是O(N^2)。在他最坏的情况下会出现歪脖子树。也就是确定一次两个数在哪边(递归一边查找,歪脖子树),共要向下递归N次。

思路: 下面的思路就是找到两条路径,用找链表的公共节点的方法来找最近公共节点。需要注意的就是在放入栈之后要进行判断下面没有就要进行出栈。

class Solution {
public:bool Getpath(TreeNode* root, TreeNode* g,stack<TreeNode*>& path){if(root==nullptr){return false;}path.push(root);//只要不是空就放进来if(root==g){return true;}if(Getpath(root->left,g,path)){return true;}if(Getpath(root->right,g,path)){return true;}path.pop();return false;}TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {stack<TreeNode*> qpath,ppath;Getpath(root,p,ppath);Getpath(root,q,qpath);while(ppath.size()!=qpath.size()){if(ppath.size()>qpath.size()){ppath.pop();}else{qpath.pop();}}while(ppath.top()!=qpath.top()){ppath.pop();qpath.pop();}return ppath.top();}
};

二叉搜索树与双向链表

在这里插入图片描述

思路: 该题目要求了空间复杂度,要是不要求的话,直接就中序遍历就好了。将节点prev指向空,cur为4的指针,这里要注意成员函数prev的引用,是必须要带上的,不带会影响整个结构的。将cur以递归的路径进行,prev跟上cur之前的节点。通过cur->left=prev,prev->right=cur。

class Solution {
public:void InorderConvert(TreeNode* cur,TreeNode*& prev){if(cur==nullptr){return;}InorderConvert(cur->left,prev);cur->left=prev;if(prev){prev->right=cur;}prev=cur;InorderConvert(cur->right,prev);}TreeNode* Convert(TreeNode* pRootOfTree) {TreeNode* prev=nullptr;InorderConvert(pRootOfTree,prev);TreeNode* root=pRootOfTree;while(root&&root->left){root=root->left;}return root;}
};

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

在这里插入图片描述

思路: 将中序遍历的数组进行划区域处理,ibegin,iend,iroot,中序前序两个数组比较这进行。具体看代码。

class Solution {
public:TreeNode* _buildTree(vector<int>& preorder, vector<int>& inorder,int& prei,int ibegin,int iend){if(ibegin>iend){return nullptr;}TreeNode* root=new TreeNode(preorder[prei]);int iroot=ibegin;while(iroot<=iend){if(preorder[prei]==inorder[iroot]){break;}else{iroot++;}}prei++;root->left= _buildTree(preorder,inorder,prei,ibegin,iroot-1);root->right= _buildTree(preorder,inorder,prei,iroot+1,iend);return root;}TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {int prei=0;return _buildTree(preorder,inorder,prei,0,preorder.size()-1);}
};

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

在这里插入图片描述

思路: 该题和上一个题的思路是相同的,就是将前序改为后序了,所以就是prei改为从后开始遍历。

class Solution {
public:TreeNode* _buildTree(vector<int>& preorder, vector<int>& inorder,int& prei,int ibegin,int iend){if(ibegin>iend){return nullptr;}TreeNode* root=new TreeNode(preorder[prei]);int iroot=ibegin;while(iroot<=iend){if(preorder[prei]==inorder[iroot]){break;}else{iroot++;}}prei--;root->right= _buildTree(preorder,inorder,prei,iroot+1,iend);root->left= _buildTree(preorder,inorder,prei,ibegin,iroot-1);return root;}TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {int prei=postorder.size()-1;return _buildTree(postorder,inorder,prei,0,postorder.size()-1);}
};

二叉树的前序遍历(非递归)

在这里插入图片描述

思路: 创建一个数组和一个找,是将树的左子树先进行都先进入数组按顺序。并且将前面进入数组的节点放入栈当中,之后进行对右子树的遍历,这时要将指向右子树的这颗节点进行删除在栈当中。

class Solution {
public:vector<int> preorderTraversal(TreeNode* root) {vector<int> v;stack<TreeNode*> s;TreeNode* cur=root;while(cur || !s.empty()){while(cur){v.push_back(cur->val);s.push(cur);cur=cur->left;}TreeNode* top=s.top();s.pop();cur=top->right;}return v;}
};

二叉树的中序遍历(非递归)

在这里插入图片描述

思路: 它的思路是和上一道题的解法是相同的,就是将pop出的节点,挨个放入数组。

class Solution {
public:vector<int> inorderTraversal(TreeNode* root) {vector<int> v;stack<TreeNode*> s;TreeNode* cur=root;while(cur || !s.empty()){while(cur){s.push(cur);cur=cur->left;}TreeNode* top=s.top();v.push_back(top->val);s.pop();cur=top->right;}return v;}
};

二叉树的后续遍历

在这里插入图片描述

思路: 他与上述的问题差距就是如何让右子树在节点的前面输出,而采用的方法就是创建一个变量,用于判断是否右子树已经在父节点前面输出了。

class Solution {
public:vector<int> postorderTraversal(TreeNode* root) {vector<int> v;stack<TreeNode*> s;TreeNode* cur=root;TreeNode* pre=nullptr;while(cur || !s.empty()){while(cur){s.push(cur);cur=cur->left;}TreeNode* top=s.top();if(top->right==nullptr || pre==top->right){v.push_back(top->val);pre=top;s.pop();}else{cur=top->right;}     }return v;}
};

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

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

相关文章

GitLab 删除项目

1.点击头像 2.点击Profile 3.选择要删除的项目点进去 4.settings-general-Advances-expand 5.然后在弹出框中输入你要删除的项目名称即可

Java - 注解开发

注解开发定义bean Component的衍生注解 Service&#xff1a; 服务层的注解 Repository&#xff1a; 数据层的注解 Controller&#xff1a; 控制层的注解 纯注解开发 bean管理 bean作用范围 在类上面添加Scope(“singleton”) // prototype: 非单例 bean生命周期 PostCon…

关于Spring的bean的相关注解以及其简单使用方法

一、前置工作 第一步&#xff1a;创建一个maven项目 第二步&#xff1a;在resource中创建一个名字叫做spring-config.xml的文件&#xff0c;并把以下代码复制粘贴 <?xml version"1.0" encoding"UTF-8"?> <beans xmlns"http://www.sprin…

redis-cluster 创建及监控

集群命令 cluster info&#xff1a;打印集群的信息。 cluster nodes&#xff1a;列出集群当前已知的所有节点&#xff08;node&#xff09;的相关信息。 cluster meet <ip> <port>&#xff1a;将ip和port所指定的节点添加到集群当中。 cluster addslots <slot…

《Federated Unlearning via Active Forgetting》论文精读

文章目录 1、概述2、方法实验主要贡献框架概述 3、实验结果比较方法实验结果忘却完整性忘却效率模型实用性 4、总结 原文链接&#xff1a; Federated Unlearning via Active Forgetting 1、概述 对机器学习模型隐私的⽇益关注催化了对机器学习的探索&#xff0c;即消除训练数…

基于JAVA SpringBoot和Vue高考志愿填报辅助系统

随着信息技术在管理中的应用日益深入和广泛&#xff0c;管理信息系统的实施技术也越来越成熟&#xff0c;管理信息系统是一门不断发展的新学科&#xff0c;任何一个机构要想生存和发展&#xff0c;要想有机、高效地组织内部活动&#xff0c;就必须根据自身的特点进行管理信息时…

学习笔记|大模型优质Prompt开发与应用课(二)|第二节:超高产文本生成机,传媒营销人必备神器

文章目录 01 文字写作技能的革新&#xff0c;各行各业新机遇四大类常见文字工作新闻记者的一天新闻记者的一天–写策划prompt 新闻记者的一天–排采访prompt生成结果prompt生成结果 大模型加持&#xff0c;文字写作我们如何提效营销创作营销创作-使用预置法为不同平台生成文案p…

Aspose.cell excel转pdf日期格式不正确yyyy/MM/dd变成MM/dd/yyyy

最近使用Aspose.cell将excel转pdf过程中excel中时间格式列的显示和excel表里的值显示不一样。 excel里日期格式 yyyy/MM/dd pdf里日期格式MM/dd/yyyy 主要原因&#xff1a;linux和windows里内置的时间格式不一致&#xff0c;当代码部署到linux服务器的时候转换格式就会发生不一…

Nginx 高可用负载均衡(三种模式)

一、nginx普通集群负载均衡 1、安装keepalived (1)下载 https://www.keepalived.org/download.html(2)解压 tar -zxvf keepalived-2.0.18.tar.gz(3)使用configure命令配置安装目录与核心配置文件所在位置&#xff1a; ./configure --prefix/usr/local/keepalived --sysconf/e…

Python解码张三的法外狂徒之旅,揭秘视频背后的真相!【含jS逆向解密】

前言 嗨喽&#xff0c;大家好呀~这里是爱看美女的茜茜呐 传说中&#xff0c;有人因为只是远远的看了一眼法外狂徒张三就进去了&#x1f602; 我现在是获取他视频&#xff0c;岂不是直接终生了&#x1f929; 网友&#xff1a;赶紧跑路吧 &#x1f60f; 好了话不多说&#xff…

【Android】底层逻辑深入了解(学习笔记)(未完)

step by step. 目录 init启动 Zygote进程&#xff1a; SystemServer处理过程 Binder&#xff1a; Launcher启动过程 Android系统启动流程 四大组件 Activity Service BroadcastReceiver广播 ContentProvider内容提供者&#xff08;进程内和进程间的数据共享&#xff…

vue的组件化编程的详细讲解加代码演示

&#x1f600;前言 本片文章是vue系列第5篇整理了vue的组件化编程的详细讲解加代码演示 &#x1f3e0;个人主页&#xff1a;尘觉主页 &#x1f9d1;个人简介&#xff1a;大家好&#xff0c;我是尘觉&#xff0c;希望我的文章可以帮助到大家&#xff0c;您的满意是我的动力&am…

linux安装nginx遇到的报错

1、Linux如何修改只读文件&#xff08;以设置自动连网为例&#xff09; vim /etc/sysconfig/network-scripts/ifcfg-ens33 然后提示 E45&#xff1a;已设定选项“readonly”&#xff08;请加&#xff01;强制执行&#xff09; 如果需要强制修改&#xff0c;可以使用&#xff0…

activemq消息中间件

ActiveMQ消息中间件详解 下载地址&#xff1a;https://activemq.apache.org/activemq-5015009-release 1、MQ的产品种类 1.1、消息中间件的特性/共同特性/共同维度 Kafka&#xff08;大数据专用、由java/scala编写&#xff09; API发送和接收MQ的高可用性MQ的集群和容错配置…

【vue3】获取字典数据,封装为公共方法

前言: 后台项目中基本上都有字典管理页面,Vue封装字典数据的主要目的是为了方便数据的管理和使用 不管在哪个页面使用下拉框,el-select的options数据源需要通过调用接口获取到,不同的数据源调用不同的接口,引入和使用都是不小的工作量,如果使用字典数据管理,不管同个页…

【Spring Cloud Gateway 新一代网关】—— 每天一点小知识

&#x1f4a7; S p r i n g C l o u d G a t e w a y 新一代网关 \color{#FF1493}{Spring Cloud Gateway 新一代网关} SpringCloudGateway新一代网关&#x1f4a7; &#x1f337; 仰望天空&#xff0c;妳我亦是行人.✨ &#x1f984; 个人主页——微风撞见云的博客&a…

linux NDK交叉编译rtmp 与 ffmpeg+rtmp交叉编译(v7a,v8a) 完成流程

最近在学RTMP,记录一下完成的编译流程 我是mac 电脑,但是mac上编译一直通过不了,后来才换到服务器上编译, 其实mac也能编译,只是最开始踩到坑里面了… 这里记录一下linux编译完整流程 环境: NDK: android-ndk-r17cFfmpeg: ffmpeg4.2.2 (高版本也可以编译)system: mac 1. …

【Python】Python 网络编程 ( Socket 套接字简介 | Socket 套接字使用步骤 | Socket 套接字服务端与客户端开发 )

文章目录 一、Socket 套接字简介1、Socket 套接字概念2、Socket 套接字类型3、Socket 套接字使用步骤4、Socket 套接字服务端与客户端 二、Socket 服务端与客户端开发1、服务端2、客户端3、执行结果 一、Socket 套接字简介 1、Socket 套接字概念 Socket 套接字 是一种 进程之间…

什么是 web3?

在百度搜索引擎输入 “Web3”、“大厂”。跳出来基本都是这样的标题. 以及如今的互联网行业 “哀鸿遍野”&#xff0c;不仅内卷&#xff0c;还裁员。然后掀起一阵风&#xff0c;猛吹 Web3 的好&#xff0c;数据回归用户……最后再 “威逼利诱” 一下&#xff0c;Web3 就是 20 年…

剑指 Offer 37. 序列化二叉树 / LeetCode297. 二叉树的序列化与反序列化(二叉树遍历(深度优先搜索))

题目&#xff1a; 链接&#xff1a;剑指 Offer 37. 序列化二叉树&#xff1b;LeetCode 297. 二叉树的序列化与反序列化 难度&#xff1a;困难 序列化是将一个数据结构或者对象转换为连续的比特位的操作&#xff0c;进而可以将转换后的数据存储在一个文件或者内存中&#xff0…