当前位置: 首页 > news >正文

算法_队列+宽度优先搜索---持续更新

文章目录

  • 前言
  • N叉树的层序遍历
    • 题目要求
    • 题目解析
    • 代码如下
  • 二叉树最大宽度
    • 题目要求
    • 题目解析
    • 代码如下
  • 在每个树中找最大值
    • 题目要求
    • 题目解析
    • 代码如下
  • 二叉树的锯齿形层序遍历
    • 题目要求
    • 题目解析
    • 代码如下

前言

本文将会向你介绍有关队列+宽度优先搜索的题目:N叉树的层序遍历、二叉树最大宽度、在每个树中找最大值、二叉树的锯齿形层序遍历

N叉树的层序遍历

https://leetcode.cn/problems/n-ary-tree-level-order-traversal/

题目要求

在这里插入图片描述

题目解析

根据题意,需要把一个N叉树的节点值进行层序遍历并返回,层序遍历(按照树的层级顺序逐层访问每个节点,从上到下,从左到右进行遍历)
使用队列进行宽度优先搜索的原因:

1、先进先出:队列遵循先进先出原则,这跟我们从上到下每层依次遍历的访问顺序相符,先进先出就能确保每一层的节点都在前一层的节点之后被访问
2、动态管理节点:在遍历过程中,遍历该层节点结束,我们就需要移除该层节点,添加下一层节点,队列允许我们在遍历时将当前节点添加到队列的末尾,同时能从前端取下访问的节点
3、层级控制:通过使用队列,可以轻松控制当层的节点数量,可以将其子节点加入队列,并在处理完当前层的所有节点后再处理下一层的节点。

这道题也可以说是宽搜的模板,要求理解+记忆

总体思路(忽略一些细节):
先将根节点加入到队列中,然后遍历该层的当前节点的所有子节点,并将被遍历到的节点pop并保存,然后将该层(根节点)的每个节点的子节点添加到队列当中,总的来说,就是先统计该层的节点,再统计该层节点的所有子节点,这样就能统计遍历出N叉树的所有节点

代码如下

/*
// Definition for a Node.
class Node {
public:int val;vector<Node*> children;Node() {}Node(int _val) {val = _val;}Node(int _val, vector<Node*> _children) {val = _val;children = _children;}
};
*/
class Solution {
public:vector<vector<int>> levelOrder(Node* root) {vector<vector<int>> ret;    //保存每一层遍历的结果queue<Node*> q;q.push(root);if(root == nullptr) return ret;//将N叉树的节点加入到队列当中while(q.size()){int sz = q.size();vector<int> tmp;    //统计本层的节点for(int i = 0; i < sz; i++){Node* t = q.front();q.pop();tmp.push_back(t->val);//将该层的每一个节点的子节点加入到队列中for(Node* child : t->children){q.push(child);}}ret.push_back(tmp);}return ret;}
};

二叉树最大宽度

https://leetcode.cn/problems/maximum-width-of-binary-tree/description/

题目要求

在这里插入图片描述

题目解析

本题的要求是求出二叉树所有层中最大的宽度,有了第一题的基础,那么这道题也用宽搜解决。 注意:这个宽度并不是示例中每一层的节点数,而是将每层的第一个节点和最后一个节点之间的nullptr都需要补齐后的宽度。 比如这棵二叉树的最大宽度就是4

在这里插入图片描述

这些宽搜题大致思想还是一样的,这里没有使用队列,而是采用vector数组,因为我们可以用数组首元素的下标和尾部元素的下标相减加一就是该层的宽度
本质上还是队列的思想:将下一层的节点添加完毕后,直接覆盖原有的保存节点的容器(将该层节点覆盖)
值得注意的是我们将根节点作为下标1位置,该节点的右节点的下标位置为下标*2,左节点的下标位置为下标位置 *2+1

代码如下

/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode() : val(0), left(nullptr), right(nullptr) {}*     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}*     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}* };*/
class Solution {
public:int widthOfBinaryTree(TreeNode* root) {vector<pair<TreeNode*, unsigned int>> q;    //用数组模拟队列,方便计算每层宽度q.push_back({root, 1});   //下标从1开始unsigned int ret = 0;   //最大宽度while(q.size()){//计算本层的宽度auto& [x1, y1] = q[0];  //提取pairauto& [x2, y2] = q.back();ret = max(ret, y2 - y1 + 1);//将下一层添加到队列vector<pair<TreeNode*, unsigned int>> tmp;  //创建一个新队列存储下一层的节点for(auto& [x, y] : q){if(x->right) tmp.push_back({x->right, y * 2});if(x->left) tmp.push_back({x->left, y * 2 + 1});}q = tmp;    }return ret;}
};

在每个树中找最大值

https://leetcode.cn/problems/hPov7L/description/

题目要求

在这里插入图片描述

题目解析

题目要求返回每一层的最大值,该题的思路与前两道相似,属于简单题 利用层序遍历,遍历每一层所有节点,算出最大值 注意:-231 <= Node.val <= 231 - 1

代码如下

class Solution {
public:vector<int> largestValues(TreeNode* root) {queue<TreeNode*> q;vector<int> ret;   if(root == nullptr) return ret;q.push(root);while(q.size()){int tmp = INT_MIN;    //记录每一层的最大值(注意:节点的值可能取到-2^31//计算本层的最大值int sz = q.size();for(int i = 0; i < sz; i++){auto t = q.front();q.pop();tmp = max(tmp, t->val);if(t->right) q.push(t->right);if(t->left) q.push(t->left);}ret.push_back(tmp);}return ret;}
};

二叉树的锯齿形层序遍历

https://leetcode.cn/problems/binary-tree-zigzag-level-order-traversal/description/

题目要求

在这里插入图片描述

题目解析

锯齿形层序遍历也就是在层序遍历的基础上:偶数反着来,奇数正常来
加一个标志位,用来表示该层是奇数层还是偶数层即可,具体思路与前些题相似,不再多赘述
在这里插入图片描述

代码如下

/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode() : val(0), left(nullptr), right(nullptr) {}*     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}*     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}* };*/
class Solution {
public:vector<vector<int>> zigzagLevelOrder(TreeNode* root) {vector<vector<int>> ret;int flag = 1;     //标记奇数偶数行if(root == nullptr) return ret;queue<TreeNode*> q;q.push(root);//层序遍历while(q.size()){int sz = q.size();vector<int> tmp;for(int i = 0; i < sz; i++){auto t = q.front(); //获取当前层的当前节点q.pop();if(flag % 2 != 0) tmp.push_back(t->val);else tmp.insert(tmp.begin(), t->val);//注意层序遍历需要先将左子节点入队,再将右子节点入队if(t->left) q.push(t->left);if(t->right) q.push(t->right);}ret.push_back(tmp);flag++;}return ret;}
};

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 数据库C语言删除修改和输出
  • 6. LinkedList与链表
  • LLM大模型学习:AI大模型原理、应用与未来趋势!
  • 大模型实战一、Ollama+RagFlow 部署本地知识库
  • yolov5 +gui界面+单目测距 实现对图片视频摄像头的测距
  • 屏幕空间UV 警戒线
  • 氚云,低代码领风者如何破解行业的“中式焦虑”?
  • 首个大模型供应链安全领域的国际标准,WDTA《大模型供应链安全要求》标准解读
  • 【复盘】近期博客内容升级
  • [Linux]:文件(下)
  • 网络编程9.10
  • 爆改YOLOv8|利用yolov9的ADown改进卷积Conv-轻量化
  • 速盾:高防 cdn 分布式防御攻击?
  • JVM合集
  • 【AI学习】AI科普:专有名词介绍
  • [iOS]Core Data浅析一 -- 启用Core Data
  • 《Java8实战》-第四章读书笔记(引入流Stream)
  • 【mysql】环境安装、服务启动、密码设置
  • cookie和session
  • Java 内存分配及垃圾回收机制初探
  • Lsb图片隐写
  • Markdown 语法简单说明
  • miniui datagrid 的客户端分页解决方案 - CS结合
  • Python_OOP
  • select2 取值 遍历 设置默认值
  • SpringBoot几种定时任务的实现方式
  • Vue小说阅读器(仿追书神器)
  • 动态魔术使用DBMS_SQL
  • 诡异!React stopPropagation失灵
  • 老板让我十分钟上手nx-admin
  • 爬虫模拟登陆 SegmentFault
  • 验证码识别技术——15分钟带你突破各种复杂不定长验证码
  • Spring第一个helloWorld
  • 曾刷新两项世界纪录,腾讯优图人脸检测算法 DSFD 正式开源 ...
  • "无招胜有招"nbsp;史上最全的互…
  • # MySQL server 层和存储引擎层是怎么交互数据的?
  • #define与typedef区别
  • #pragma 指令
  • (4)(4.6) Triducer
  • (delphi11最新学习资料) Object Pascal 学习笔记---第13章第1节 (全局数据、栈和堆)
  • (DenseNet)Densely Connected Convolutional Networks--Gao Huang
  • (env: Windows,mp,1.06.2308310; lib: 3.2.4) uniapp微信小程序
  • (js)循环条件满足时终止循环
  • (Mirage系列之二)VMware Horizon Mirage的经典用户用例及真实案例分析
  • (python)数据结构---字典
  • (Pytorch框架)神经网络输出维度调试,做出我们自己的网络来!!(详细教程~)
  • (二)linux使用docker容器运行mysql
  • (附源码)ssm本科教学合格评估管理系统 毕业设计 180916
  • (官网安装) 基于CentOS 7安装MangoDB和MangoDB Shell
  • (七)Flink Watermark
  • (五)网络优化与超参数选择--九五小庞
  • (学习日记)2024.03.12:UCOSIII第十四节:时基列表
  • (一)模式识别——基于SVM的道路分割实验(附资源)
  • (转)iOS字体
  • (转)大道至简,职场上做人做事做管理