欢迎光临
我们一直在努力

《LeetCode 662 二叉树最大宽度 队列宽搜BFS解法》

一.题目

662. 二叉树最大宽度 – 力扣(LeetCode)

二.思路讲解

        2.1 思路讲解

        本题要求计算二叉树的最大宽度,即每一层最左非空节点到最右非空节点之间的长度(包括中间的空节点)。         如果能够为每个节点分配一个唯一的位置编号,那么同层最右节点的编号减去最左节点的编号再加 1 就是该层的宽度。         这种编号方式可以借鉴堆的数组存储思想:假设根节点编号为 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});
unsigned int ret = 0;
while(q.size())
{
//先更新本层宽度
auto& [x1,y1] = q[0];//获取队头
auto& [x2,y2] = q.back();//获取队尾
ret = max(ret,y2 – y1 + 1);

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

四.代码讲解

一、数据结构与初始化
  • q:使用 vector<pair<TreeNode*, unsigned int>> 模拟队列,存储当前层的节点及其位置编号。根节点编号为 1。

  • ret:记录当前遇到的最大宽度,初始为 0。

二、主循环:逐层处理

        当 q 非空时,表示还有节点未处理,继续循环。

1. 计算当前层宽度

  • 取出当前层队列的第一个节点(即最左节点)的编号 y1。

  • 取出当前层队列的最后一个节点(即最右节点)的编号 y2。

  • 当前层宽度为 y2 – y1 + 1,更新全局最大值 ret。

2. 生成下一层节点

创建一个临时数组 tmp,用于存放下一层的节点及其编号。

  • 遍历当前层队列的每个节点 (x, y):

    • 如果左子节点存在,则将其编号设为 y * 2,并加入 tmp。

    • 如果右子节点存在,则将其编号设为 y * 2 + 1,并加入 tmp。

  • 将 q 更新为 tmp,即进入下一层。

三、关键细节
  • 编号规则:根节点编号为 1,左子节点编号为 2*父节点编号,右子节点编号为 2*父节点编号+1。这与堆的数组存储一致,能够准确反映节点的相对位置。

五、流程图

赞(0)
未经允许不得转载:171主机测评 » 《LeetCode 662 二叉树最大宽度 队列宽搜BFS解法》
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址