算法_队列+宽度优先搜索

news2024/11/14 19:58:09

文章目录

  • 前言
  • 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];  //提取pair
            auto& [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;
    }
};

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

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

相关文章

目标检测-RT-DETR

RT-DETR (Real-Time Detection Transformer) 是一种结合了 Transformer 和实时目标检测的创新模型架构。它旨在解决现有目标检测模型在速度和精度之间的权衡问题&#xff0c;通过引入高效的 Transformer 模块和优化的检测头&#xff0c;提升了模型的实时性和准确性。RT-DETR 可…

Linux-实用指令

目录 前言 指定运行级别 基本介绍 切换运行级别 指令类 帮助指令 man 获得帮助信息 help指令 文件目录类 pwd指令 ls指令 cd指令 mkdir命令 rmdir指令删除空目录 touch指令 cp指令 rm指令 mv指令 cat指令 more指令 less指令 echo指令 head指令 tail指令…

2024.9.6 作业

手写unique_ptr指针指针 代码&#xff1a; #include <iostream> #include <stdexcept>template <typename T> class unique_ptr { public:// 构造函数explicit unique_ptr(T* ptr nullptr) : m_ptr(ptr) {}// 析构函数~unique_ptr() {delete m_ptr;}// 禁…

设置GB/T35114服务

GB/T35114服务是下联模式&#xff0c;支持GB/T35114标准A级双向认证&#xff0c;支持国密系列硬件设备。 操作步骤 在配置-》设备-》级联配置-》GB服务配置 进行编辑。 1、点击 编辑 2、修改国标服务器地址 3、如果其他参数也需要修改&#xff0c;都可自定义&#xff0c;除了国…

FME教程:通过更新读模块,解决FME读取shapefile数据,提示意外输入,“在转换中,某些读取的要素与工作空间的要素类不匹配……”的问题

目录 一、问题情况 二、解决方法 一、问题情况 在使用制作好的FME模板读取shapefile数据时&#xff0c;有时候会遇到弹窗提示意外输入&#xff0c;模板无法运行&#xff0c;在日志信息中警示“在转换中&#xff0c;某些读取的要素与工作空间的要素类不匹配。可能由于读模块的…

2024年全国大学生数学建模竞赛(E题) 建模解析|交通流量管控|小鹿学长带队指引全代码文章与思路

我是鹿鹿学长&#xff0c;就读于上海交通大学&#xff0c;截至目前已经帮200人完成了建模与思路的构建的处理了&#xff5e; 本篇文章是鹿鹿学长经过深度思考&#xff0c;独辟蹊径&#xff0c;实现综合建模。独创复杂系统视角&#xff0c;帮助你解决国赛的难关呀。 完整内容可以…

【前端学习】AntV G6-06 使用图算法

课程链接 图算法 Algorithm | G6 (antgroup.com) 【例子 pageRank】 ​​​​​​力导向图布局 | G6 (antgroup.com) 重点部分添加注释 import G6 from antv/g6;const { pageRank } G6.Algorithm; // 在此引入 pageRankconst container document.getElementById(containe…

无人机之报警器的作用

一、紧急救援与辅助搜救 紧急救援&#xff1a;在事故或紧急情况下&#xff0c;无人机报警器可以迅速发出警报&#xff0c;指引救援人员前往事故地点&#xff0c;提高救援效率。 辅助搜救&#xff1a;无人机搭载报警器可以辅助寻找失踪人员或其他需要搜救的场景&#xff0c;通…

MySQL数据库的介绍

目录 1.什么是MySQL数据库 2.MySQL数据库的设计 MySQL的进一步认识 MySQL的客户端 —— mysql MySQL的服务端 —— mysqld 3.MySQL数据库的架构 MySQL架构图 连接层 服务层 存储引擎层 文件系统层 4.MySQL的存储引擎 认识存储引擎 MySQL中的存储引擎 存储引擎之…

电工类 ,今日行业动态

电工类今日行业动态 一、技术发展趋势 智能化、自动化推进&#xff1a;随着人工智能、物联网等技术的不断发展&#xff0c;电工行业正逐步向智能化、自动化转型。智能电网、智能家居等领域的快速发展&#xff0c;对电工技术提出了新的要求&#xff0c;电工人员需要不断学习和…

使用matplotlib绘制散点图、柱状图和饼状图-学习篇

一、散点图 Python代码如下&#xff1a; num_points 100 x np.random.rand(num_points) #x点位随机 y np.random.rand(num_points) #y点位随机 colors np.random.rand(num_points) #颜色随机 sizes 1000 * np.random.rand(num_points) # 大小随机 alphas np.random.ran…

网络安全评测评技术与标准

网络安全测评概况 概念 参照一定的标准规范要求&#xff0c;通过一系列技术和管理方法&#xff0c;获取评估对象网络安全状况信息&#xff0c;对其给出相应网络安全情况综合判定 测评对象&#xff1a;信息系统的组成要素或信息系统自身 CC&#xff08;Common Criteria&#…

Versioned Staged Flow-Sensitive Pointer Analysis

VSFS 1.Introduction2.Approach2.1.相关概念2.2.VSFS 3.Evaluation参考文献 1.Introduction 上一篇blog我介绍了目前flow-sensitive pointer analysis常用的SFS算法。相比IFDS-based方法&#xff0c;SFS显著通过稀疏分析提升了效率&#xff0c;但是其内部依旧有许多冗余计算&a…

12道经典性能测试人员面试题

1.性能测试包含了哪些软件测试&#xff08;至少举出3种&#xff09;&#xff1f; 参考答案&#xff1a;负载测试、压力测试、容量测试。 负载测试&#xff08;Load Testing&#xff09;&#xff1a;负载测试是一种主要为了测试软件系统是否达到需求文档设计的目标&#xff0c…

Linux系统编程实现ls -l | wc -l指令

由于该指令是通过管道的形式实现的&#xff0c;所以我们要使用系统函数pipe。ls -l |wc -l的作用就是统计当前目录有多少文件。如果又父进程实现ls -l&#xff0c;子进程实现wc -l指令&#xff0c;代码如下&#xff1a; #include<unistd.h> #include<stdio.h> #in…

帝可得智能售货机运营管理系统

1.项目介绍 帝可得是一个基于物联网概念下的智能售货机运营管理系统 应用场景&#xff1a;智能家居、共享充电中、智能售货机 智能售货机的优势在于其自我管理能力 。 物联网技术&#xff1a;像是售货机的顺风耳和千里眼。 智能分析与推荐 人员设备绑定管理 移动支付支持…

下一代皮克斯:AI如何融合电影与游戏

故事是人类体验的核心,通过故事我们理解世界、寻找意义并与他人建立联系。技术的进步不断推动着故事叙述的形式,从迪士尼的多平面摄影机到皮克斯的3D图形技术,每一次技术革命都带来了故事叙述的新方式。 游戏:现代叙事的前沿 今天,有两个主要的趋势正在加速下一代叙事公…

球球大作战

代码&#xff1a; #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdbool.h> #include<graphics.h> #include<stdlib.h> #include<conio.h> #include<time.h>//随机数库文件 #include<math.h> #include<tchar.h…

单点登录CAS

CAS&#xff08;Central Authentication Service&#xff09;是耶鲁大学发起的一个开源项目&#xff0c;旨在为Web应用系统提供一种可靠的单点登录解决方案。CAS服务器独立部署&#xff0c;作为独立的Web应用&#xff0c;负责处理用户的认证请求并颁发票据&#xff08;Ticket&a…

P0.7全倒装COB超微小间距LED显示屏厂家已量产,加速高清显示的发展

随着P0.7全倒装COB超微小间距LED显示屏技术的成功量产&#xff0c;这一里程碑式的成就不仅标志着高清显示技术迈入了全新纪元&#xff0c;更预示着未来视觉体验将迎来前所未有的变革。各大应用场景&#xff0c;如指挥中心、会议中心、大型活动直播、高端影院乃至家庭娱乐&#…