【算法】队列+bfs算法 解决树的相关算法题(C++)

文章目录

  • 1. 前言
  • 2. 算法题
    • 429.N叉树的层序遍历
    • 103.二叉树的锯齿形层序遍历
    • 662.二叉树最大宽度
    • 515.在每个树行中找最大值

1. 前言

队列 宽度优先算法(BFS)是解决很多算法问题的常见工具。

BFS通过逐层遍历图或树的节点来寻找解决问题的最短路径或最短步骤。使用队列可以很好地支持BFS算法的实现。

下面是一个使用队列和宽度优先算法解决问题的一般步骤:

  1. 创建一个空队列,并将起始节点放入队列中。
  2. 创建一个集合用于记录已经访问过的节点,防止重复访问。(visited数组,一般用于路径、迷宫问题)
  3. 初始化其他必要的辅助数据结构,例如距离数组或状态数组等。
  4. 开始循环,直到队列为空:
    • 从队列中取出一个节点作为当前节点。
    • 如果当前节点是目标节点,说明找到了解,结束搜索。
    • 否则,将当前节点的所有未访问过的邻居节点加入队列,并将这些节点标记为已访问。
  5. 如果需要记录路径或其他信息,可以在搜索过程中相应地更新辅助数据结构。
  6. 如果队列为空,说明不存在解。

使用队列和宽度优先算法可以解决许多问题,例如迷宫问题、最短路径问题、连通性问题等。具体的实现方式可能因问题而异,但基本思路是相似的。


2. 算法题

429.N叉树的层序遍历

在这里插入图片描述

思路

  • 解法队列,宽度优先搜索
    在这里插入图片描述

    1. 如上图所写,首先将根节点入队
    2. 循环队列,直至队列为空:
      3. q.size即为该层节点数,循环q.size次:提取出队头节点,并将该节点的所有子节点入队
    3. 每遍历一层,将结果加入到结果数组ret中

代码

vector<vector<int>> levelOrder(Node* root) {
    vector<vector<int>> ret; // 最终结果
    queue<Node*> q; // 用队列记录节点
    // 将本层元素放入队列,提取出值后出队,将子节点入队
    if(root) q.push(root);
    else    return ret;
    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); // tmp记录该层节点值
            for(Node* child : t->children) // 当前节点的子节点入队
            {
                if(child) // 不为空
                    q.push(child);
            }
        }
        ret.push_back(tmp); // 更新结果
    }
    return ret;
}

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

在这里插入图片描述

思路

  • 题意分析:要求按照先从左往右进行一层遍历、再从左往右进行下一层遍历,重复遍历完二叉树
    • 我们可以将其理解为奇数层正序遍历(从左向右),偶数层逆序遍历
  • 解法队列,宽度优先搜索
  • 该题与上一道很类似,只需要添加一个遍历用于标记当前层为奇数还是偶数,用于判断逆序还是正序
    1. 使用一个队列来存储当前层的所有节点,同时记录当前层的节点数。
    2. 依次从队列中取出节点,将其值加入到当前层的结果集tmp中,并将其左右子节点加入队列中。
    3. 如果当前层为偶数层,则需要将tmp逆序后再加入到结果集ret中。
    4. 最后返回结果集ret。

代码

vector<vector<int>> zigzagLevelOrder(TreeNode* root) {
    // 锯齿形层序遍历:偶数层逆序遍历,奇数层正常遍历
    vector<vector<int>> ret;
    queue<TreeNode*> q;
    if(!root) return ret;
    else q.push(root);
    int level = 1; // 根据flag判断是否逆序
    while(q.size())
    {
        int sz = q.size(); // 记录本层个数
        vector<int> tmp;
        for(int i = 0; i < sz; ++i)
        {
            TreeNode* t = q.front();
            q.pop();
            tmp.push_back(t->val);
            if(t->left) q.push(t->left);
            if(t->right) q.push(t->right);
        }
        if(level % 2 == 0)   reverse(tmp.begin(), tmp.end());
        ret.push_back(tmp);
        ++level;
    }
    
    return ret;
}

662.二叉树最大宽度

在这里插入图片描述

思路

  • 题意分析:即返回二叉树的最大宽度,即最大层的宽度
  • 解法:记录节点下标、数组表示队列
    在这里插入图片描述
    • 如上图的思路,我们用数组表示队列,队列中存放pair类型,分别为节点和其对应的下标
    1. 将根节点及其下标1插入队列,进行循环,直至队列为空
    2. 提取队尾和队头两元素(即为该层的最左最有的节点)并记录 / 更新结果
    3. 将该层的所有子节点入队
    4. 最后返回结果ret

代码

int widthOfBinaryTree(TreeNode* root) {
    // 队列(数组)存储节点及其下标(补全null节点后的下标)
    vector<pair<TreeNode*, unsigned int>> q;
    // q.push_back(make_pair<nullptr, 0>); 
    if(!root) return 0;
    else q.push_back({root, 1}); // // 根节点从1下标开始
    unsigned int ret = 0; // 最终结果

    while(q.size())
    {
        // 计算本层宽度
        auto [node1, x1] = q[0]; // 提取一个pair类型
        auto [node2, x2] = q.back();
        ret = max(ret, x2 - x1 + 1);

        vector<pair<TreeNode*, unsigned int>> tmp; // tmp存储下一层节点信息,覆盖q
        for(auto& [node, x] : q)
        {
            // 左孩子下标:2x 右孩子下标:2x+1
            if(node->left) tmp.push_back({node->left, 2*x});
            if(node->right) tmp.push_back({node->right, 2*x + 1});
        }

        q = tmp;
    }
    return ret;
}

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

在这里插入图片描述

思路

  • 解法队列 + 层序遍历
  • 直接利用队列队树进行层序遍历即可
  • 每层循环定义一次变量maxVal用于寻找最大值

代码

vector<int> largestValues(TreeNode* root) {
    vector<int> ret; // 结果数组
    queue<TreeNode*> q; // 队列用于层序遍历
    if(!root) return ret;
    else q.push(root);
    
    while(!q.empty())
    {
        int sz = q.size();
        int maxVal = INT_MIN; // 用于比较节点大小 
        while(sz--)
        {
            auto t = q.front(); // 提取当前节点
            q.pop();
            maxVal = max(maxVal, t->val);
            if(t->left) q.push(t->left);
            if(t->right) q.push(t->right);
        }
        ret.push_back(maxVal);
    }

    return ret;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

画图案例分享

案例 1 from scipy.misc import derivative from scipy.integrate import quad import matplotlib.pyplot as plt import numpy as np import pandas as pd from scipy.stats import norm import warningsplt.style.use(ggplot) np.random.seed(37) warnings.filterwarnings(i…

《Linux C编程实战》笔记:出错处理

这一节书上把它放到线程这一章&#xff0c;按理说应该在前面就讲了 头文件errno.h定义了变量errno&#xff0c;它存储了错误发生时的错误码&#xff0c;通过错误码可以得到错误的信息 程序开始执行时&#xff0c;变量errno被初始化为0。很多库函数在执行过程中遇到错误时就会…

排序算法9----计数排序(C)

计数排序是一种非比较排序&#xff0c;不比较大小 。 1、思想 计数排序又称为鸽巢原理&#xff0c;是对哈希直接定址法的变形应用。 2、步骤 1、统计数据&#xff1a;统计每个数据出现了多少次。&#xff08;建立一个count数组&#xff0c;范围从[MIN,MAX],MAX代表arr中…

关于gltf模型格式文件的学习

目录 glTF模型 小黄鸭的gltf模型 字段分析 scene nodes meshes primitives attributes indices mode material accessors bufferView byteOffset count componentType type materials textures images samplers magFilter与minFilter wrapS与wrapT 进行…

10个用于Android开发的有用的Kotlin库及示例

10个用于Android开发的有用的Kotlin库及示例 在Android开发领域&#xff0c;Kotlin已成为一门领先的语言&#xff0c;带来了现代语法和功能的浪潮。随着Kotlin的崛起&#xff0c;涌现出了许多专为其定制的库&#xff0c;进一步增强了开发体验。本文将深入介绍其中的10个库&…

2024年美赛数学建模思路 - 案例:异常检测

文章目录 赛题思路一、简介 -- 关于异常检测异常检测监督学习 二、异常检测算法2. 箱线图分析3. 基于距离/密度4. 基于划分思想 建模资料 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 一、简介 – 关于异常…

C语言从入门到实战——动态内存管理

动态内存管理 前言一、 为什么要有动态内存分配二、 malloc和free2.1 malloc2.2 free 三、calloc和realloc3.1 calloc3.2 realloc 四、常见的动态内存的错误4.1 对NULL指针的解引用操作4.2 对动态开辟空间的越界访问4.3 对非动态开辟内存使用free释放4.4 使用free释放一块动态开…

赤藓糖醇行业研究:预计2029年将达到3.5亿美元

赤藓糖醇是一种四碳糖醇&#xff0c;存在于多种食物中&#xff0c;如葡萄、梨、西瓜等&#xff0c;可由微生物发酵法和化学合成法两种方法制备&#xff0c;目前商业化生产中均采用微生物发酵法。赤藓糖醇由葡萄糖发酵制作而成&#xff0c;上游原料主要包括葡萄糖、玉米淀粉糖和…

Android中的anr定位指导与建议

1.背景 8月份安卓出现了一次直播间卡死(ANR)问题&#xff0c;且由于排查难度较大&#xff0c;持续了较长时间。本文针对如何快速定位安卓端出现ANR问题进行总结和探讨. 这里大致补充一下当时的情况,当时看到情景的是从某一个特定的场景下进入直播间后整个直播间界面立刻就卡住…

23年11月移动广告行业大盘趋势,借鉴双 11 ,年货节该如何提高广告收益

前言 年货节开始啦&#xff0c;我们可以借鉴2023年双11期间的广告大盘趋势&#xff0c;洞悉如何在大型促销期间调整广告运营策略以提升效果。年货节是一个绝佳的时机&#xff0c;可以利用在双11期间积累的经验和策略&#xff0c;进行相应的调整和优化。通过精准定位广告投放高…

Elasticsearch:和 LIamaIndex 的集成

LlamaIndex 是一个数据框架&#xff0c;供 LLM 应用程序摄取、构建和访问私有或特定领域的数据。 LlamaIndex 是开源的&#xff0c;可用于构建各种应用程序。 在 GitHub 上查看该项目。 安装 在 Docker 上设置 Elasticsearch 使用以下 docker 命令启动单节点 Elasticsearch 实…

maven无法识别本地maven仓库包解决方案

前言&#xff1a;由于本地maven仓库已经有了相关依赖包&#xff0c;idea还是去远程仓库下载(不知何原因&#xff0c;生产上到远程仓库的网络突然不通了)&#xff0c;故需要自己本地上传相关包到生产主机并修改setttings文件来强制读取本地仓库方案 settings文件修改如下方式即…

iPad如何连接到Wi-Fi,这里提供详细步骤

这篇文章解释了如何将iPad连接到Wi-Fi&#xff0c;无论是公共Wi-Fi网络还是需要密码的专用网络。 将iPad连接到Wi-Fi 当你想让iPad联机时&#xff0c;请按照以下步骤连接到Wi-Fi&#xff1a; 1、在iPad的主屏幕上&#xff0c;点击设置。 2、点击Wi-Fi。 3、要启动iPad搜索附…

数据库作业三

1.创建student和score表 2.为student表和score表增加记录 3.查询student表的所有记录 4.查询student表的第2条到4条记录 5.从student表查询所有学生的学号&#xff08;id&#xff09;、姓名&#xff08;name&#xff09;和院系&#xff08;department&#xff09;的信息 6.从st…

Zabbix6.4 图形乱码怎么办

Zabbix6.4 图形乱码怎么办 Zabbix6.4 安装后&#xff0c;进入主机图形展示&#xff0c;你会发现文字部分乱成了乱码。 找一台Microsoft Windows 7/10/11的电脑&#xff0c;打开C:\Windows\Fonts 找到【楷体 常规】&#xff0c;将字体复制到桌面。 桌面上就会多出simkai.ttf字…

5.2 基于深度学习和先验状态的实时指纹室内定位

文献来源 Nabati M, Ghorashi S A. A real-time fingerprint-based indoor positioning using deep learning and preceding states[J]. Expert Systems with Applications, 2023, 213: 118889.&#xff08;5.2_基于指纹的实时室内定位&#xff0c;使用深度学习和前一状态&…

抖音弹幕直播玩法汉字找不同文字找不同无人值执守自动玩游戏自带语音播报的开发日志

#找不同# 要解决如下几个问题&#xff1a; 1.声音sprite的录制和调用&#xff0c;解决方案以及解决库如下&#xff1a; howler.min.js://一款不错的音频播放js库。 2.鼠标自动飘浮,使用的库 anime.min.js 3.资源预加载 preload.min.js 4.其它使用到的库 jquery,vue

Docker安装开源Blog(Typecho)

前言 首先这个镜像是centos7.9进行安装PHP环境&#xff0c;然后挂载目录去运行的&#xff0c;镜像大概300MB左右&#xff0c;没学过PHP&#xff0c;没办法给Dockerfile文件 参考文章&#xff1a;Docker安装Typecho | D-y Blog感知不强&#xff0c;图一乐https://www.wlul.top…

开放式耳机哪个品牌好?2024最新开放式耳机选购指南!实测避雷!

如果你是一个对音质和舒适度有要求的人&#xff0c;那么你一定要看看开放式耳机了&#xff0c;开放式耳机不是像封闭式耳机那样堵着耳朵&#xff0c;它能够提供更宽广的音场和更自然声音&#xff0c;佩戴也更加舒适&#xff0c;那么哪个品牌的开放式耳机最好呢&#xff1f;接下…

新能源汽车智慧充电桩解决方案:智慧化综合管理与数字化高效运营

一、方案概述 TSINGSEE青犀&触角云新能源汽车智慧充电桩解决方案基于管理运营平台&#xff0c;覆盖业务与应用、数据传输与梳理、多端开发、搭建等模块&#xff0c;融合AI、5G、Wi-Fi 、移动支付等技术&#xff0c;实现充电基础设施由数字化向智能化演进&#xff0c;通过构…