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

news2024/11/18 3:30:26

文章目录

  • 前言
  • 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/2133200.html

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

相关文章

【每日一题】LeetCode 2398.预算内的最多机器人数目(滑动窗口、数组、二分查找、前缀和、堆(优先队列))

【每日一题】LeetCode 2398.预算内的最多机器人数目&#xff08;滑动窗口、数组、二分查找、前缀和、堆&#xff08;优先队列&#xff09;&#xff09; 题目描述 给定两个整数数组 chargeTimes 和 runningCosts&#xff0c;分别代表 n 个机器人的充电时间和运行成本。再给定一…

喂料机和失重秤的区别?

喂料机和失重秤的区别&#xff1f;在硬件结构上的具体差异&#xff1a; 1. 喂料机的硬件结构 喂料机的结构比较简单&#xff0c;主要功能是传送物料&#xff0c;不涉及精确的称重系统。其硬件结构通常包括以下部分&#xff1a; 料斗&#xff1a;用于存储物料&#xff0c;物料…

cesium.js 入门到精通(7)

我们说一下相机的概念&#xff1a; 生活中的相机是一个用来拍照的设备&#xff0c;而这里的相机应该理解成一个人机交互的媒介。地图的缩放、平移、旋转&#xff0c;以及相关的鼠标操作都是由相机作为媒介来实现的。相机的位置和姿态参数决定了我们能看到的地图的样子。 可以…

centos7.9安装clamav教程

本章教程主要记录在centos7.9安装clamav过程。 ClamAV(Clam AntiVirus)是一个开源的防病毒软件工具,主要用于检测和消除恶意软件。它最初由 Tomasz Kojm 于 2001 年开发,并由 Cisco Systems 维护和支持。ClamAV 广泛应用于邮件网关、文件服务器和其他需要防病毒保护的环境中…

Linux软件包循环依赖解决 彻底删除i386架构 更新软件源

0.问题 之前为了wine和intel核显驱动加了32位的库&#xff0c;现在每次apt upgrade更新都被循环依赖弄得不堪其扰&#xff0c;apt --fix-broken install解决缺失都循环报错&#xff0c;寸步难行&#xff0c;忍无可忍、 而且一看全是i386的依赖&#xff0c;这32位我不用也罢&…

apache文件共享和访问控制

实现apache文件共享 文件共享路径 <Directory "/var/www/html"> #默认发布路径&#xff0c;功能限制 Options Indexes FollowSymLinks #indexes支持文件共享功能 AllowOverride None Require all granted </Directory> 进入到该路径下 cd…

【Java Bean Validation API】Spring3 集成 Bean 参数校验框架

Spring3 集成 Bean 参数校验框架 Java Bean Validation API 1. 依赖 Spring 版本&#xff1a;3.0.5 Java 版本&#xff1a;jdk21 检验框架依赖&#xff08;也可能不需要&#xff0c;在前面 spring 的启动依赖里就有&#xff09;&#xff1a; <!-- 自定义验证注解 -->…

【原创】java+springboot+mysql高校社团网系统设计与实现

个人主页&#xff1a;程序猿小小杨 个人简介&#xff1a;从事开发多年&#xff0c;Java、Php、Python、前端开发均有涉猎 博客内容&#xff1a;Java项目实战、项目演示、技术分享 文末有作者名片&#xff0c;希望和大家一起共同进步&#xff0c;你只管努力&#xff0c;剩下的交…

spring内置的

程序里注入了spring内置的线程池&#xff0c;但没有看到线程池相关参数配置&#xff08;corePoolSize maxPoolSize 队列大小&#xff09;&#xff0c;网上查说默认是1个线程&#xff0c;结果和生产实际看到的不一致。 从生产可以看到有8个线程在跑&#xff0c;task-1 task-8&am…

buildroot移植qt报错Info: creating stash file (补充qt添加字库)

移植qt库&#xff0c;编译文件报错Info: creating stash file /home/rbing/QT/uart/.qmake.stash Project ERROR: Unknown module(s) in QT: serialport rbingouc:~/QT/uart$ /home/rbing/linux/tool/buildroot-2022.02.9/output/host/usr/bin/qmake Info: creating stash fil…

PCI Express 体系结构导读摘录(六)

系列文章目录 PCI Express 体系结构导读摘录&#xff08;一&#xff09; PCI Express 体系结构导读摘录&#xff08;二&#xff09; PCI Express 体系结构导读摘录&#xff08;三&#xff09; PCI Express 体系结构导读摘录&#xff08;四&#xff09; PCI Express 体系结构导读…

HarmonyOS开发实战( Beta5.0)画笔调色板案例实践

鸿蒙HarmonyOS开发往期必看&#xff1a; HarmonyOS NEXT应用开发性能实践总结 最新版&#xff01;“非常详细的” 鸿蒙HarmonyOS Next应用开发学习路线&#xff01;&#xff08;从零基础入门到精通&#xff09; 介绍 本示例实现了一个网格渐变的画笔调色板&#xff0c;能够根…

Vector - VT System - 板卡_VT板卡使用介绍_01

总体介绍 在常规的车载网络测试中&#xff0c;除了我们常用的使用VN系列设备进行总线协议测试&#xff0c;大多数公司都会将协议强相关的功能测试放在了功能侧&#xff0c;但是实际上这块对于车载网络测试工程师来说也是需要去了解的&#xff0c;毕竟只有懂协议的人才能更好的测…

Python with 关键字语法糖

参考文章: Python with 关键字 | 菜鸟教程 (runoob.com)https://www.runoob.com/python3/python-with.html Python 中的 with 语句用于异常处理&#xff0c;封装了 try…except…finally 编码范式&#xff0c;提高了易用性。 with 语句使代码更清晰、更具可读性&#xff0c; 它…

Fake Location模拟定位,刷跑 “运动世界校园”

前言:"科技改变生活&#xff0c;如果本文章对你有帮助&#xff0c;别忘记留下你的点赞&#xff0c;以下我对环境特变刁钻的运动世界校园为实例&#xff0c;也是成功安全正常上传数据&#xff0c;如果遇到问题&#xff0c;请留言评论区&#xff0c;所有链接我会放在文章头部…

157-安全开发-Python 自动化挖掘项目SRC 目标FOFA 资产Web 爬虫解析库

案例一&#xff1a;Python-WEB 爬虫库&数据解析库 这里开发的内容不做过多描述&#xff0c;贴上自己写的代码 爬取数据 要爬取p标签&#xff0c;利用Beautyfulsoup模块 import requests,time from bs4 import BeautifulSoup#url"https://src.sjtu.edu.cn/rank/firm…

99AutoML 自动化机器学习实践--NNI 自动化机器学习工具包

NNI 自动化机器学习工具包 NNI 是 Neural Network Intelligence 的缩写&#xff0c;可以译作&#xff1a;智能神经网络。名字听起来陌生&#xff0c;但 NNI 实际上就是一个自动化机器学习工具包。它通过多种调优的算法来搜索最好的神经网络结构和超参数&#xff0c;并支持单机、…

【Fastapi】使用Pandas作为大数据分析处理工具

【Fastapi】使用Pandas作为大数据分析处理工具 gitee https://gitee.com/zz1521145346/fastapi_frame.git github https://github.com/zz001357/fastapi_frame.git 准备工作 能联接的sql软件&#xff08;如&#xff0c;mysql&#xff09; 安装pandas &#xff08;pip in…

vue3 使用swiper制作带缩略图的轮播图

效果图 实现代码 <template><div class"wrap"><!-- 主轮播图 --><swiper :style"{--swiper-navigation-color: #fff,--swiper-pagination-color: #fff,}" :modules"modules" :navigation"true" :thumbs"{ …

深圳建站公司-如何做网站

深圳建站公司&#xff1a;如何制作一个成功的网站 在信息化快速发展的今天&#xff0c;企业和个人越来越重视网络形象&#xff0c;网站成为了展示品牌、推广产品和服务的重要平台。深圳作为科技创新和经济发展的前沿城市&#xff0c;涌现出许多专业的建站公司&#xff0c;能够为…