二叉树——队列bfs专题

1.N叉树的层序遍历

我们之前遇到过二叉树的层序遍历,只需要用队列先进先出的特性就可以达到层序遍历的目的。

而这里不是二叉树,也就是说让节点的孩子入队列时不仅仅是左右孩子了,而是它的所有孩子。而我们看这棵多叉树的构造,它的孩子是存储在数组中的。所以我们在让孩子入队时只需要依次让数组中的所有节点入队列即可。

class Node 
{
public:int val;vector<Node*> children;
};

而这道题的要求是返回一个二维数组,数组的元素就是每一层的层序遍历结果。

我们关键点就在于如果确定元素属于那一层,方法就是在进行层序遍历前,我们先统计该队列的大小,大小即使这一层元素的个数,当这个数变为0,表示这一层的元素已经统计完了,这时队列中的就是下一层的元素了。此时重复求大小和层序遍历的过程即可。

class Solution 
{
public:vector<vector<int>> levelOrder(Node* root) {if(root == nullptr) return {};queue<Node*> q;q.push(root);vector<vector<int>> ret;int currentFloorSize = 0;while(!q.empty()){vector<int> currentFloor;currentFloorSize = q.size();while(currentFloorSize--){Node* head = q.front(); //获取队头元素for(int i=0; i<head->children.size(); ++i) //让队头孩子入队{q.emplace(head->children[i]);}currentFloor.emplace_back(head->val);//保存队头valq.pop();//出队}ret.emplace_back(currentFloor);}return ret;}
};

2.二叉树的锯齿形层序遍历

依旧是二叉树的层序遍历,只不过在遍历的时候有顺序之分,奇数层从左到右,偶数层从右到左。

解法依旧是先采取正常的层序遍历,多定义一个flag变量用了记录当前是奇数还是偶数。当把这一行统计完毕后,在将该结果插入到数组之前,先对flag进行判断,如果是偶数就插入反转之后的数组,如果奇数则直接插入即可。

class Solution 
{
public:vector<vector<int>> zigzagLevelOrder(TreeNode* root) {if(root == nullptr) return {};// 根节点入队列queue<TreeNode*> q;q.emplace(root);vector<vector<int>> ret;int currentFloorSize =0;int flag = 1; // 遍历层的方向,奇数层left->right, 偶数层right->leftwhile(!q.empty()){currentFloorSize = q.size();vector<int> currentFloorEele;while(currentFloorSize--){   // 保存节点数据TreeNode* head = q.front();q.pop();currentFloorEele.emplace_back(head->val);// 孩子入队列if(head->left) q.emplace(head->left);if(head->right) q.emplace(head->right);}if(flag % 2 == 0)reverse(currentFloorEele.begin(), currentFloorEele.end());ret.emplace_back(currentFloorEele);flag++;}return ret;}
};

3.在每个树行中找最大值

题目要求返回一个数组,数组的元素都是二叉树每一层的最大值。

解法:我们只需要在进行层序遍历的过程中,进行最大值的统计即可。当遍历完该层后,直接保存最大值即可。

class Solution 
{
public:
vector<int> largestValues(TreeNode* root) {if(root == nullptr) return {};queue<TreeNode*> q;q.emplace(root);vector<int> ret;int currentFloorSize = 0;while(!q.empty()){currentFloorSize = q.size();int maxVal = INT_MIN;while(currentFloorSize--){auto head = q.front();q.pop();maxVal = max(maxVal, head->val);if(head->left) q.emplace(head->left);if(head->right) q.emplace(head->right);}ret.emplace_back(maxVal);}return ret;}
};

 4.二叉树最大深度

返回所有层中最宽的。其中,我们只需要看每一层的最左和最右即可,其中也要计算中间的空节点。

解法:我们将二叉树以顺序方式进行存储,存储对用的根节点以及对应的下标。其实就是堆的存储方式。当我们根节点从0开始,他的左右孩子可以通过2*x+1,2*x+2得来。这样下来,每一层的宽度其实就是最左与最右节点的下标的差值+1.

class Solution 
{
public:int widthOfBinaryTree(TreeNode* root) {vector<pair<TreeNode*, unsigned int>> LevelSize; // 模拟队列,将二叉树以顺序结构存储unsigned int ret = 0; // 统计结果LevelSize.emplace_back(root, 0);while(!LevelSize.empty()){// 取出该层的首尾节点,并更新结果auto& [x1, y1] = LevelSize[0];auto& [x2, y2] = LevelSize.back();ret = max(ret, y2 - y1 + 1);// 让孩子入队vector<pair<TreeNode*, unsigned int>> tmp; // 临时存储下一层的节点,最后覆盖原队列for(auto& [x, y] : LevelSize){if(x->left) tmp.emplace_back(x->left, y * 2 + 1);if(x->right) tmp.emplace_back(x->right, y * 2 + 2);}// 更新层LevelSize = tmp;}return ret;}
};

说明:我们这里使用数组来模拟的队列,因为我们让孩子入队列后得头删上一层的元素,在数组中头删消耗比较大,所以我们可以用一个临时数组来统计下一层的元素,之后用临时数组覆盖原数组即可。

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

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

相关文章

Python高级爬虫之JS逆向+安卓逆向1.1节-搭建Python开发环境

目录 引言&#xff1a; 1.1.1 为什么要安装Python? 1.1.2 下载Python解释器 1.1.3 安装Python解释器 1.1.4 测试是否安装成功 1.1.5 跟大神学高级爬虫安卓逆向 引言&#xff1a; 大神薯条老师的高级爬虫安卓逆向教程&#xff1a; 这套爬虫教程会系统讲解爬虫的初级&…

Windows 安装和使用 ElasticSearch

SpringBoot3 整合 Elasticsearch 1. ElasticSearch 1.1 ES &#xff08;1&#xff09;ES 是一个开源的分布式搜索和分析引擎&#xff0c;专为处理大模型数据而设计&#xff0c;它能够实现近乎实时的数据检索、分析和可视化&#xff0c;广泛用于全文搜索、日志分析和监控&…

matplotlib初探

库引入 import matplotlib.pyplot as pltpyplot.figure 创建新图形或激活现有图形

NVM 多版本Node.js 管理全指南(Windows系统)

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家、全栈领域优质创作者、高级开发工程师、高级信息系统项目管理师、系统架构师&#xff0c;数学与应用数学专业&#xff0c;10年以上多种混合语言开发经验&#xff0c;从事DICOM医学影像开发领域多年&#xff0c;熟悉DICOM协议及…

实验室预约|实验室预约小程序|基于Java+vue微信小程序的实验室预约管理系统设计与实现(源码+数据库+文档)

实验室预约小程序 目录 基于微信小程序的实验室预约管理系统设计与实现 一、前言 二、系统功能设计 三、系统实现 1、微信小程序前台 2、管理员后台 &#xff08;1&#xff09;管理员登录 &#xff08;2&#xff09;实验室管理 &#xff08;3&#xff09;公告信息管理…

SpringBoot底层-数据源自动配置类

SpringBoot默认使用Hikari连接池&#xff0c;当我们想要切换成Druid连接池&#xff0c;底层原理是怎样呢 SpringBoot默认连接池——Hikari 在spring-boot-autoconfiguration包内有一个DataSourceConfiguraion配置类 abstract class DataSourceConfiguration {Configuration(p…

面试算法高频03-递归

认识递归 递归的概念与特性&#xff1a;递归本质类似循环&#xff0c;是通过函数体进行的循环操作。借助电影《盗梦空间》类比&#xff0c;递归如同主角在不同梦境层穿梭&#xff0c;向下进入不同递归层&#xff0c;向上能回到原来一层&#xff0c;每一层环境和周围元素相似&a…

linux Gitkraken 破解

ubuntu 安装 Gitkraken 9.x Pro 版本_gitcracken.git-CSDN博客

设计模式简述(十一)装饰器模式

装饰器模式 描述基本使用使用 描述 装饰器模式是一种功能型模式 用于动态增强对象的功能 这么一说感觉上和代理模式有些类似 抽象装饰器 要实现原有业务接口&#xff0c;并注入原有业务对象 至于对原有业务对象的调用&#xff0c;可以采用private业务对象 实现业务接口方法的…

【NetCore】ControllerBase:ASP.NET Core 中的基石类

ControllerBase:ASP.NET Core 中的基石类 一、什么是 ControllerBase?二、ControllerBase 的主要功能三、ControllerBase 的常用属性四、ControllerBase 的常用方法2. 模型绑定与验证3. 依赖注入五、ControllerBase 与 Controller 的区别六、实际开发中的最佳实践七、总结在 …

DE2-115分秒计数器

一、模块设计 如若不清楚怎么模块化&#xff0c;请看https://blog.csdn.net/szyugly/article/details/146379170?spm1001.2014.3001.5501 1.1顶层模块 module top_counter(input wire CLOCK_50, // 50MHz时钟input wire KEY0, // 暂停/继续按键out…

ubuntu git cola gui

直接的方法&#xff0c; samba&#xff0c; win 里用 tortoiseSVN 需要先在命令行&#xff0c;运行 git 命令&#xff0c;看到操作提示&#xff0c; 按照提示做 然后右键看 git diff 其它的方法 linux下可视化git工具git-cola安装与使用&#xff08;HTTP方式&#xff09;_git…

每日一题(小白)回溯篇4

深度优先搜索题&#xff1a;找到最长的路径&#xff0c;计算这样的路径有多少条&#xff08;使用回溯&#xff09; 分析题意可以得知&#xff0c;每次向前后左右走一步&#xff0c;直至走完16步就算一条走通路径。要求条件是不能超出4*4的范围&#xff0c;不能重复之前的路径。…

【数据分享】2000—2020年我国250m精度灌溉农田栅格数据(免费获取)

灌溉农田是指通过水利灌溉为农作物提供必要水分&#xff0c;以维持其生长需求的农田类型。灌溉农田占全球农田的20%&#xff0c;占全球粮食产量的40%。但其消耗了60%-70%的淡水和80%-90%的消耗性用水量。中国是世界上灌溉面积最大的农业大国&#xff0c;但中国仅占世界上8%的农…

MySQL-SQL-DML语句、INSER添加数据、UPDATE更新数据、DELETE删除数据

一. DML 1. DML的英文全称是Data Manipulation Language(数据操作语言)&#xff0c;用来对数据库中表的数据记录进行增、删、改操作。 2. 添加数据(INSERT)&#xff1b;修改数据(UPDATE)&#xff1b;删除数据(DELETE) 二. DML-INSER添加数据 -- DML insert -- 指定字段添加数…

使用SymPy求解矩阵微分方程

引言 在数学、物理、工程等领域,微分方程常常被用来描述系统的变化和动态过程。对于多变量系统或者多方程系统,矩阵微分方程是非常常见的,它可以用来描述如电路、控制系统、振动系统等复杂的动态行为。今天,我们将通过Python 中的 SymPy 库来求解矩阵微分方程,帮助大家轻…

Sentinel实战(五)、系统保护规则、限流后统一处理及sentinel持久化配置

Spring Cloud Alibaba-Sentinel实战(五)、系统保护规则、限流后统一处理及sentinel持久化配置 一、系统保护规则一)、系统规则支持的模式二)、新增系统规则界面三)、demo测试二、限流后统一处理实操demo三、sentinel持久化配一、系统保护规则 系统保护规则是从应用级别的…

【百日精通JAVA | SQL篇 | 第四篇】约束

SQL这一块没什么难度&#xff0c;主要是一个熟练度&#xff0c;稍微上点难度的地方&#xff0c;其实在于查&#xff0c;比较复杂&#xff0c;涉及到很多问题。 指定列插入 使用指定列插入的时候&#xff0c;未被指定的列使用默认值进行存储&#xff0c;默认值为空。 默认值设置…

http协议版本的区别 -- 2和3

目录 http2和http3的区别 传输层协议 QUIC协议 介绍 连接建立与握手 建立安全连接的过程 RTT 建连为什么需要两个过程 原因 解决 QUIC协议的1-RTT 建连 必要性 连接过程 第一次握手(Client Hello) 版本号 key_share 其他 第二次握手 介绍 Server Hello 身…

21 天 Python 计划:MySQL 库相关操作

文章目录 前言一、系统数据库1. information_schema2. performance_schema3. mysql4. test 二、创建数据库1. 语法2. 数据库命名规则 三、数据库相关操作1. 查看数据库2. 选择数据库3. 删除数据库4. 修改数据库 总结 前言 Python是一种强大且易于学习的编程语言。通过这个21天的…