【C++二叉树】进阶OJ题
【C++二叉树】进阶OJ题
目录
- 【C++二叉树】进阶OJ题
- 1.二叉树的层序遍历II
- 示例代码
- 解题思路
- 2.二叉搜索树与双向链表
- 示例代码
- 解题思路
- 3.从前序与中序遍历序列构造二叉树
- 示例代码
- 解题思路
- 4.从中序与后序遍历序列构造二叉树
- 示例代码
- 解题思路
- 5.二叉树的前序遍历(非递归迭代实现)
- 示例代码
- 解题思路
- 6.二叉树的中序遍历(非递归迭代实现)
- 示例代码
- 解题思路
- 7二叉树的后序遍历(非递归迭代实现)
- 示例代码
- 解题思路
作者:爱写代码的刚子
时间:2023.9.6
前言:本篇博客总结了一些二叉树有关的一些中等难度OJ题,总结这些题的解题思路
1.二叉树的层序遍历II
题目链接
示例代码
class Solution {
public:vector<vector<int>> levelOrderBottom(TreeNode* root) {vector<vector<int>> vv;if(!root){return vv;}queue<TreeNode*> q;q.push(root);while(!q.empty()){int curlevel = q.size();vv.push_back(vector<int> ());while(curlevel--){TreeNode *front=q.front();vv.back().push_back(front->val);q.pop();if(front->left){q.push(front->left);}if(front->right){q.push(front->right);}}}reverse(vv.begin(),vv.end());return vv;}
};
解题思路
-
选择使用队列来实现
-
-
注意这里使用变量curlevel来记录每层的元素个数,并且第二个while循环中需要curlevel来计数,因为题目中要求返回 vector<vector>,所以记录每层的元素个数是必要的。
-
由于题目要求返回自底向上的层序遍历,所以我们还需要reverse函数将vector<vector>容器进行反转。
2.二叉搜索树与双向链表
题目链接
示例代码
class Solution {
public:void test(TreeNode* cur,TreeNode*& prev){if(cur==nullptr){return;}test(cur->left,prev);cur->left=prev;if(prev)//注意prev可能为nullptr{prev->right=cur;}prev=cur;test(cur->right,prev);}TreeNode* Convert(TreeNode* pRootOfTree) {TreeNode*prev=nullptr;test(pRootOfTree,prev);TreeNode* leftover=pRootOfTree;while(leftover&&leftover->left){leftover=leftover->left;}return leftover;}
};
解题思路
- 采用中序遍历
- 由于二叉树遍历的特殊性,我们无法找到下一个遍历的对象,所以我们设立新旧指针:cur和prev,由于根节点prev未知,所以我们传入nullptr
- 我们让cur指针先走,对旧节点的指针朝向进行修改(prev的left和right指针)
- 如图:
本质其实就是让cur先走,记录先前节点(prev),并修改先前节点的指针朝向。
3.从前序与中序遍历序列构造二叉树
题目链接
示例代码
class Solution {
public:TreeNode* test(vector<int>& preorder, vector<int>& inorder,int begini,int& prei,int endi){if(begini>endi){return nullptr;}TreeNode* root=new TreeNode(preorder[prei]);int rooti=begini;while(rooti<=endi){if(preorder[prei]==inorder[rooti]){break;}else{++rooti;}}++prei;root->left=test(preorder, inorder,begini,prei,rooti-1);root->right=test(preorder, inorder,rooti+1,prei,endi);return root;}TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {int i=0;return test(preorder,inorder,0,i,preorder.size()-1);}
};
解题思路
-
前序遍历可以确定根节点的位置
-
确定了根再去中序遍历里找到对应的根
-
两者遍历的图示:
-
观察图示结构,我们可以将前序遍历中的数据从左到右进行遍历,一次将遍历的节点作为根节点
-
观察图示结构,我们利用前序遍历中定的根节点在中序遍历中找到对应的位置,用中序遍历的结构来进行递归(类似分治)
-
递归的结束条件就是递归到子叶节点时,子叶节点再进行递归,递归区间有误。(begini>endi)
4.从中序与后序遍历序列构造二叉树
题目链接
示例代码
class Solution {
public:TreeNode*test(vector<int>& inorder, vector<int>& postorder,int begini,int& prei,int endi){if(begini>endi){return nullptr;}TreeNode*root=new TreeNode(postorder[prei]);int rooti=endi;while(rooti>=begini){if(inorder[rooti]==postorder[prei]){break;}--rooti;}--prei;root->right=test(inorder, postorder,rooti+1,prei,endi);root->left=test(inorder, postorder,begini,prei,rooti-1);//root->right=test(inorder, postorder,rooti+1,prei,endi);return root;}TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {int i=postorder.size()-1;return test(inorder, postorder,0,i,i);}
};
解题思路
-
思路与《从中序与后序遍历序列构造二叉树》类似,先画图:
-
我们发现与《从中序与后序遍历序列构造二叉树》这道题中的结构类似,所以考虑后序遍历序列从右往左遍历,依次将访问的节点作为根节点
-
注意!后序遍历中访问完根节点后访问的是右节点,所以我们应先构造右子树,将《从中序与后序遍历序列构造二叉树》题中的示例代码中两个递归入口交换顺序即可
5.二叉树的前序遍历(非递归迭代实现)
题目链接
示例代码
class Solution {
public:vector<int> preorderTraversal(TreeNode* root) {vector<int> v;stack<TreeNode*> st;TreeNode* tmp=root;while(tmp||!st.empty()){while(tmp){v.push_back(tmp->val);st.push(tmp);tmp=tmp->left;}tmp=st.top()->right;st.pop();}return v;}
};
解题思路
- 使用vector和stack
- 先将二叉树最左边的节点push进栈,将节点储存的值push_back进vector
- 再取出栈顶元素,控制指针进入栈顶元素节点的右子树,并pop该栈顶元素,重复以上步骤
- 图示:
6.二叉树的中序遍历(非递归迭代实现)
题目链接
示例代码
class Solution {
public:vector<int> inorderTraversal(TreeNode* root) {stack<TreeNode*> st;vector<int> v;TreeNode* cur=root;while(cur||!st.empty()){while(cur){st.push(cur);cur=cur->left;}TreeNode* top=st.top();v.push_back(top->val);cur=top->right;st.pop();}return v;}
};
解题思路
过程与前序遍历类似,只是访问的时机不同,中序遍历要在所有左子树push进栈后再进行访问,并pop栈顶元素
7二叉树的后序遍历(非递归迭代实现)
题目链接
示例代码
class Solution {
public:vector<int> postorderTraversal(TreeNode* root) {stack<TreeNode*> st;vector<int> v;TreeNode* cur=root;TreeNode* prev=nullptr;while(cur||!st.empty()){while(cur){st.push(cur);cur=cur->left;}TreeNode* top=st.top();if(top->right==nullptr||top->right==prev){prev=top;v.push_back(top->val);st.pop();}else{cur=top->right;}}return v;}
};
解题思路
- 我们需要设定访问时机,当右子树已经访问完了或者没有右子树时进行访问。
- 如何判读右子树是否访问完了:要引入prev指针记录上一个访问的节点,判断prev是否等于当前节点(top)的右子树。
- 注意这里使用的是if…else语句,并不是无脑
cur=top->right
相关文章:

【C++二叉树】进阶OJ题
【C二叉树】进阶OJ题 目录 【C二叉树】进阶OJ题1.二叉树的层序遍历II示例代码解题思路 2.二叉搜索树与双向链表示例代码解题思路 3.从前序与中序遍历序列构造二叉树示例代码解题思路 4.从中序与后序遍历序列构造二叉树示例代码解题思路 5.二叉树的前序遍历(非递归迭…...

C++——vector:resize与reserve的区别,验证写入4GB大数据时相比原生操作的效率提升
resize和reserve的区别 reserve:预留空间,但不实例化元素对象。所以在没有添加新的对象之前,不能引用容器内的元素。而要通过调用push_back或者insert。 resize:改变容器元素的数量,且会实例化对象(指定或…...
基础配置xml
# 配置端口 server.port8081# 文件上传配置 # 是否支持文件上传 spring.servlet.multipart.enabledtrue # 是否支持文件写入磁盘 spring.servlet.multipart.file-size-threshold0 # 上传文件的临时目录 spring.servlet.multipart.locationd:/opt/tmp # 最大支持上传文件大小 sp…...

win环境安装SuperMap iserver和配置许可
SuperMap iServer是我国北京超图公司研发的基于跨平台GIS内核的云GIS应用服务器产品,通过服务的方式,面向网络客户端提供与专业GIS桌面产品相同功能的GIS服务,能够管理、发布多源服务,包括REST服务、OGC服务等。 SuperMap iserve…...

【Apollo学习笔记】——规划模块TASK之PIECEWISE_JERK_NONLINEAR_SPEED_OPTIMIZER(一)
文章目录 TASK系列解析文章前言PIECEWISE_JERK_NONLINEAR_SPEED_OPTIMIZER功能介绍PIECEWISE_JERK_NONLINEAR_SPEED_OPTIMIZER相关配置PIECEWISE_JERK_NONLINEAR_SPEED_OPTIMIZER流程确定优化变量定义目标函数定义约束ProcessSetUpStatesAndBoundsOptimizeByQPCheckSpeedLimitF…...
pytest parametrize多参数接口请求及展示中文响应数据
编写登陆接口 app.py from flask import Flask, request, jsonify, Responseapp Flask(__name__)app.route(/login, methods[POST]) def login():username request.form.get(username)password request.form.get(password)# 在这里编写你的登录验证逻辑if username admin…...
电视连续剧 ffmpeg 批量去掉片头片尾
思路: 一、用python获取每集的总时长 二、把每集的时间,拼接成想要的ffmpeg的剪切命令命令。 1、用python获取每集的总时长 1,安装moviepy库,直接安装太慢,换成国内的源 pip install moviepy -i http://mirrors.aliyu…...

二进制搭建kubernetes
二进制搭建kubernetes 一、常见的K8S部署方式1.Minikube2.Kubeadmin3.二进制安装部署 二、二进制搭建K8S(单台master)1.部署架构规划2.系统初始化配置3.部署 docker引擎4.部署 etcd 集群4.部署 Master 组件5.部署 Worker Node 组件6.部署网络组件 三、负载均衡部署1.配置load b…...
TDengine函数大全-系统函数
以下内容来自 TDengine 官方文档 及 GitHub 内容 。 以下所有示例基于 TDengine 3.1.0.3 TDengine函数大全 1.数学函数 2.字符串函数 3.转换函数 4.时间和日期函数 5.聚合函数 6.选择函数 7.时序数据库特有函数 8.系统函数 系统函数 TDengine函数大全DATABASECLIENT_VERSIONSE…...

北京互联网营销服务商浩希数字科技申请1350万美元纳斯达克IPO上市
来源:猛兽财经 作者:猛兽财经 猛兽财经获悉,总部位于北京的互联网营销服务商浩希数字科技(Haoxi Health Technology Limited )近期已向美国证券交易委员会(SEC)提交招股书,申请在纳斯…...
ElementUI浅尝辄止22:Alert 警告
用于页面中展示重要的提示信息。 常见于消息提示或警告框。 1.如何使用? 页面中的非浮层元素,不会自动消失。 //Alert 组件提供四种主题,由type属性指定,默认值为info。<template><el-alerttitle"成功提示的文案&…...

HCIP的mgre实验
题目 拓扑图 IP地址配置和缺省 R1 [r1]int g0/0/1 [r1-GigabitEthernet0/0/1]ip add 192.168.1.1 24 Aug 2 2023 20:38:20-08:00 r1 %%01IFNET/4/LINK_STATE(l)[0]:The line protocol IP on the interface GigabitEthernet0/0/1 has entered the UP state. [r1-GigabitEtherne…...
redis cluster集群搭建
集群搭建 启动6个redis实例 创建6份配置文件 mkdir redis-cluster cd redis-cluster mkdir 7001 7002 7003 8001 8002 80037001文件夹创建配置文件redis.conf port 7001 cluster-enabled yes cluster-config-file nodes-7001.conf cluster-node-timeout 5000 appendonly ye…...

小红书笔记爬虫
⭐️⭐️⭐️⭐️⭐️欢迎来到我的博客⭐️⭐️⭐️⭐️⭐️ 🐴作者:秋无之地 🐴简介:CSDN爬虫、后端、大数据领域创作者。目前从事python爬虫、后端和大数据等相关工作,主要擅长领域有:爬虫、后端、大数据…...
国密GmSSL v2版本命令行方式生成国密sm2私钥、公钥、签名和验证签名
前言 GmSSL是国密算法的工具库(主要包含SM2、SM3、SM4和国密SSL证书生成等功能),项目本身是OpenSSL的分支,但是截至文章发布为止,OpenSSL主分支的国密算法并不完善,目前并不支持签名和解签,所以…...

2023年9月惠州/深圳CPDA数据分析师认证找弘博创新
CPDA数据分析师认证是大数据方面的认证,助力数据分析人员打下扎实的数据分析基础知识功底,为入门数据分析保驾护航。 帮助数据分析人员掌握系统化的数据分析思维和方法论,提升工作效率和决策能力,遇到问题能够举一反三,…...

it运维监控管理平台,统一运维监控管理平台
随着系统规模的不断扩大和复杂性的提高,IT运维管理的难度也在逐步增加。为了应对这一挑战,IT运维监控管理平台应运而生。本文将详细介绍IT运维监控管理平台的作用和优势以及如何选择合适的平台。 IT运维监控管理平台的作用管理平台 IT运维监控管理平台是…...

TDengine 官网换了新“皮肤”,来看看这个风格是不是你的菜
改版升级,不同以“网”!为了更好地服务客户,让大家能够更便捷、清晰地了解我们的产品和功能,我们决定给 TDengine 官网换个新“皮肤”~精心筹备下,新官网终于成功与大家见面啦——https://www.taosdata.com/。TDengine…...

MFC:自绘CListBox,GetText返回一个乱码
问题描述 自绘CListBox,GetText返回一个乱码,并且还会伴随以下断言 解决方案 ListBox Control 属性【Has Strings】改为True即可...
shell 脚本发布前后端代码
shell 脚本发布前后端代码 1、发布前端2、发布后端 1、发布前端 #! /bin/bashif [ ! $1 ] thenecho "this command needs 1 parameters"exit fiif [ -d "/usr/local/nginx/html/xxxx-$1" ] thenecho "file exists: /usr/local/nginx/html/xxxx-$1, p…...
Spring Boot 实现流式响应(兼容 2.7.x)
在实际开发中,我们可能会遇到一些流式数据处理的场景,比如接收来自上游接口的 Server-Sent Events(SSE) 或 流式 JSON 内容,并将其原样中转给前端页面或客户端。这种情况下,传统的 RestTemplate 缓存机制会…...

如何在看板中体现优先级变化
在看板中有效体现优先级变化的关键措施包括:采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中,设置任务排序规则尤其重要,因为它让看板视觉上直观地体…...

CentOS下的分布式内存计算Spark环境部署
一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架,相比 MapReduce 具有以下核心优势: 内存计算:数据可常驻内存,迭代计算性能提升 10-100 倍(文档段落:3-79…...

2021-03-15 iview一些问题
1.iview 在使用tree组件时,发现没有set类的方法,只有get,那么要改变tree值,只能遍历treeData,递归修改treeData的checked,发现无法更改,原因在于check模式下,子元素的勾选状态跟父节…...
Nginx server_name 配置说明
Nginx 是一个高性能的反向代理和负载均衡服务器,其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机(Virtual Host)。 1. 简介 Nginx 使用 server_name 指令来确定…...

Linux-07 ubuntu 的 chrome 启动不了
文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了,报错如下四、启动不了,解决如下 总结 问题原因 在应用中可以看到chrome,但是打不开(说明:原来的ubuntu系统出问题了,这个是备用的硬盘&a…...

第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词
Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵,其中每行,每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid,其中有多少个 3 3 的 “幻方” 子矩阵&am…...

学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2
每日一言 今天的每一份坚持,都是在为未来积攒底气。 案例:OLED显示一个A 这边观察到一个点,怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 : 如果代码里信号切换太快(比如 SDA 刚变,SCL 立刻变&#…...

分布式增量爬虫实现方案
之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面,避免重复抓取,以节省资源和时间。 在分布式环境下,增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路:将增量判…...

HashMap中的put方法执行流程(流程图)
1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中,其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下: 初始判断与哈希计算: 首先,putVal 方法会检查当前的 table(也就…...