目录
队列仿佛就是为了BFS而诞生的
一、N叉树的层序遍历


queue,拿出队头元素,这个元素孩子进队
如何分层?记录每层元素
一次循环仅处理该层元素,处理细节即让该层元素入一维数组,同时让该层元素的孩子(如果存在)就入队列。
class Solution {
public:
vector<vector<int>> levelOrder(Node* root) {
vector<vector<int>> ret;
queue<Node*> q;//队列处理节点
//特殊情况处理
if(root==nullptr)return ret;
q.push(root);
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* children:t->children)
{
if(children!=nullptr)
q.push(children);
}
}
//记录该层元素
ret.push_back(tmp);
}
return ret;
}
};
二、二叉树的锯齿形层序遍历
103. 二叉树的锯齿形层序遍历 - 力扣(LeetCode)



这种解法似乎在,周期为二的相邻两次处理步骤不同的情境(就是一次为a行为,下一次为b行为,再下一次为a行为....)中很常见
当是偶数行的时候我们将数组逆序即可,这借助rerverse很容易做到,其实思考到了偶数行需要逆序,自然会想到标记位,还有rerverse逆序数组。
class Solution {
public:
vector<vector<int>> zigzagLevelOrder(TreeNode* root) {
vector<vector<int>> ret;
queue<TreeNode*> q;
if(root==nullptr)return ret;
q.push(root);
//标记位,初始值设置为一个奇数
int level =1;
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;
}
};
三*、二叉树的最大宽度



我们可以给二叉树结点编号,这样我们通过编号相减,很容易就能得到长度
找最左最右结点,通过q.front和q.back很容易实现

需要注意的是,根节点编号0和1的孩子结点的编号的计算规则不一样
编号0:左孩子2x+1,右孩子2x+1
编号1:左孩子2x,右孩子2x+1

此外需要注意的是,二叉树每一层的结点个数都是指数级增长的,如果做了加减乘除这样的操作,都可能会有越界的风险,比如该方法当层数达到1500层,下标可能会溢出

虽然下标可能会溢出,导致回绕(溢出后从负数范围最大值开始)但是因为我们做的是相减的操作,即使下标溢出变成了负数,在相减时求得的结果会修正为二者之间的距离,那么依然正确
比如这里char类型是正数最大到达127,再加一就会溢出,回绕到-128,-128-127其实是1,为啥呢,因为char范围最大存储8位,超过的会截断

截断后:00000001,即 1(因为超出 char 范围,只保留低 8 位)
但是如果是溢出一圈之后又溢出,再相减,那么就会出错,但题目说明数据在32位带符号整数范围内,所以这种情况肯定是不会出现的不用担心。

当然,为了防止溢出也可以直接采用unsigned int
class Solution {
public:
int widthOfBinaryTree(TreeNode* root) {
vector<pair<TreeNode*,unsigned int>> q;
q.push_back({root,1});
//max函数要求两个参数类型相同,所以ret也设置成unsigned int
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)tmp.push_back({x->left,y*2});
if(x->right)tmp.push_back({x->right,y*2+1});
}
q=tmp;
}
return ret;
}
};
四、在每个树行中找最大值
515. 在每个树行中找最大值 - 力扣(LeetCode)

思路:
层序遍历+找每层最大值,很简单了
class Solution {
public:
vector<int> largestValues(TreeNode* root) {
vector<int> ret;
if(root==nullptr)return ret;
queue<TreeNode*> q;
q.push(root);
while(q.size())
{
//应该开头更新maxnum!且数据有负数应该记为intmin
int maxnum=INT_MIN;
int sz=q.size();
for(int i=0;i<sz;++i)
{
TreeNode*t=q.front();
q.pop();
maxnum=max(maxnum,t->val);
if(t->left)q.push(t->left);
if(t->right)q.push(t->right);
}
ret.push_back(maxnum);
}
return ret;
}
};
此篇完。今天任务依旧很轻松呀

6988

被折叠的 条评论
为什么被折叠?



