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

【刷题19】队列+bfs专题

目录

  • 一、N叉树的层序遍历
  • 二、二叉树的锯齿形层序遍历
  • 三、二叉树的最大宽度
  • 四、在每个树行中找最大值

一、N叉树的层序遍历

题目:

在这里插入图片描述

思路:队列+bfs(具体看注释)

代码:

class Solution {
public:
    vector<vector<int>> levelOrder(Node* root) {
        vector<vector<int>> ret;
        if(root == nullptr) return ret;
        queue<Node*> q; // 队列
        q.push(root);
        while(!q.empty())
        {
            // 统计一层的节点数
            int k = q.size();

            // 在同一层的所有节点值存在一个vector里
            // 同时统计当前节点的孩子节点个数,
            // 并把当前节点的孩子节点都放入队列中
            // 删除当前节点(队头),root->下个队头节点
            vector<int> v;
            while(k--)
            {
                v.push_back(root->val);
                //
                int size = root->children.size();
                for(int i=0; i<size;i++)
                {
                    q.push(root->children[i]);
                }
                //
                q.pop();
                root = q.front();
            }
            ret.push_back(v);
        }
        return ret;
    }
};

二、二叉树的锯齿形层序遍历

题目:
在这里插入图片描述
思路:队列+bfs – 与上题大体相同(当前节点的孩子节点入队列不同)

  • 因为是“锯齿形”层序,所以可以用一个变量来控制一个vector是否要逆序

代码:

class Solution {
public:
    vector<vector<int>> zigzagLevelOrder(TreeNode* root) {
        vector<vector<int>> ret;
        if(root == nullptr) return ret;
        queue<TreeNode*> q; // 队列
        q.push(root);
        int t = 1;
        // 1: 不逆序
        // -1: 逆序
        while(!q.empty())
        {
            int k = q.size();

            vector<int> v;
            while(k--)
            {
                v.push_back(root->val);
                //
                if(root->left) q.push(root->left);
                if(root->right) q.push(root->right);
                //
                q.pop();
                root = q.front();
            }
            // t
            if(t < 0) reverse(v.begin(), v.end()); 
            t *= -1; 
            ret.push_back(v);
        }
        return ret;
    }
};

三、二叉树的最大宽度

题目:
在这里插入图片描述
思路:用数组模拟队列

  • 数组中的元素是KV,分别表示节点指针和标记的数据
    在这里插入图片描述
  • 新节点入队列的操作与前面不同,需要用一个临时的数组,把当前层的所有节点的孩子节点放入临时数组,然后再覆盖原来的“队列”
  • 计算最大宽度,当前层的第一个节点和最后节点的value值相减再+1
  • 注意数据类型,用无符号的int

代码:

class Solution {
public:
    int widthOfBinaryTree(TreeNode* root) {
        vector<pair<TreeNode*, unsigned int>> q; // 用数字模拟队列
        q.push_back({root, 1});
        unsigned int ret = 0;
        while(q.size())
        {
            auto &[x1, y1] = q[0];
            auto &[x2, y2] = q.back();
            ret = max(y2-y1+1, ret);

            vector<pair<TreeNode*, unsigned int>> tmp;// 临时数组
            for(auto &[x, y] : q)
            {
                if(x->left) tmp.push_back({x->left, 2*y});
                if(x->right) tmp.push_back({x->right, 2*y+1});
            }
            q = tmp;
        }
        return ret;
    }
};

四、在每个树行中找最大值

题目:
在这里插入图片描述

思路:

  • root为空,直接返回空的ret
  • 剩下的与层序遍历思路一样,多了比较当前层的最大值,然后最大值放入ret中
  • 注意节点值的数据范围

代码:

class Solution {
public:
    vector<int> largestValues(TreeNode* root) {
        vector<int> ret;
        queue<TreeNode*> q;
        if(root == nullptr) return ret;//
        q.push(root);//
        while(!q.empty())
        {
            int max = INT_MIN;//
            int k = q.size();
            while(k--)
            {
                if(root->val > max) max = root->val; 
                if(root->left) q.push(root->left);
                if(root->right) q.push(root->right);
                q.pop();
                root = q.front();
            }
            ret.push_back(max);
        }
        return ret;
    }
};

http://www.kler.cn/a/394584.html

相关文章:

  • 《Python Web 抓取实战:豆瓣电影 Top 250 数据抓取与分析》
  • 家政服务小程序,家政行业数字化发展下的优势
  • 使用Element UI实现前端分页,及el-table表格跨页选择数据,切换分页保留分页数据,限制多选数量
  • 【算法一周目】双指针(2)
  • 45.第二阶段x86游戏实战2-hook监控实时抓取游戏lua
  • 《C++在金融领域的技术革命:高效、安全与创新的融合》
  • 生成自签名证书并配置 HTTPS 使用自签名证书
  • uni-app快速入门(四)--maninfest.json及pages.json配置
  • CSS新特性
  • Ai编程从零开始全栈开发一个后台管理系统之用户登录、权限控制、用户管理-前端部分(十二)
  • nacos配置中心入门
  • 【达梦数据库】参数优化脚本主要改什么
  • spark.default.parallelism 在什么时候起作用,与spark.sql.shuffle.partitions有什么异同点?
  • LaTeX中浮动体(图片、表格)的位置及上下间距设置
  • 使用命令强制给ESXI上的硬盘分区
  • Grafana Username password invalid
  • JavaScript的展开运算符在React中的应用
  • 游戏引擎学习第11天
  • 软件测试计划和测试用例详解
  • 鸿蒙学习生态应用开发能力全景图-鸿蒙生态伙伴 SDK 市场(4)
  • 家政服务平台管理系统(源码+文档+部署+讲解)
  • Sql进阶:字段中包含CSV,如何通过Sql解析CSV成多行多列?
  • 【数据结构】顺序表解析及实战运用
  • 【Redis实战篇】利用布隆过滤器解决缓存穿透问题
  • 力扣题目解析--合并两个链表
  • SystemVerilog学习笔记(十一):接口