队列+宽搜例题讲解!

429. N 叉树的层序遍历

题目解析:

根据题目分析,可以看出题目要我们求的是N叉数的层序遍历,就是把每层的放在一块,最后把每层都输出出来即可!

算法分析:

我们可以利用队列先进先出的特性进行求解,这里比层序遍历多了一个条件,记录当前层有多少个节点,然后只把当前层的节点出完即可,就是一层一层的进行输出,我们需要记录每层的节点的值,所以我们应该使用一个vector存储每层的节点,然后最终将每层的结点放到最终的vector中即可!

代码:

class Solution {
public:
    vector<vector<int>> levelOrder(Node* root)
    {
        //定义一个队列用于进行出队的操作!
        queue<Node*> q;
        vector<vector<int>>ret;

        //首先判断给定的根节点是否为空,为空的话直接结束!
        if(root==nullptr)
        {
            return ret;
        }

        //不为空!
        q.push(root);
        //当队中一直存在元素时,一直进行遍历即可!
        while(q.size())
        {
            //统计出本层的节点个数!
            //只需要进行出队len次,即可完成本次的出队操作!!

            int len=q.size();
            
            for(int i=0;i<len;i++)
            {
                
                Node*tem=q.front();  //队头元素!
                q.pop();
                v.push_back(tem->val);  //将本层节点的值进行放入到vector中!
                for(Node* child:tem->children)
                {
                    //本次元素出队之后,将其孩子进行入队操作!
                    if(child)
                    {
                        q.push(child);
                    }
                }
               
            }
             ret.push_back(v);
        }
        return ret;
    }
};


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


 

题目解析:

根据题目分析我们可以得出,题目要让我们第一次进行从左向右遍历,第二层进行从右向左遍历,如此往复,返回最终遍历的结果!

算法分析:

对于本题,还是和之前二叉树的变量一样,只不过是多了一个条件而言,相邻的每行的遍历顺序恰好相反,所以我们可以设置一个flag变量,用于标志何时进行逆置即可!当flag满足逆置的条件时,我们把本层结点的vector进行reverse即可!

代码

class Solution {
public:
    vector<vector<int>> zigzagLevelOrder(TreeNode* root)
    {
        vector<vector<int>>ret;
        queue<TreeNode*>q;


        if(root==nullptr)
        {
            return ret;
        }
          int flag=1;
        q.push(root);
        while(q.size())
        {
            int len=q.size();
            //奇数为从左向右,偶数相反!
            //直接全部使用从左向右,对于偶数的情况!!我们只需要将得到的vector进行reverse然后再插入即可!
          
            vector<int>v;
            for(int i=0;i<len;i++)
            {
                TreeNode*tem=q.front();
                q.pop();

                v.push_back(tem->val);
                //下一层元素进行入队!
                //左右孩子入队列!
                if(tem->left)
                {
                    q.push(tem->left);
                }
                if(tem->right)
                {
                    q.push(tem->right);
                }

            }

            if(flag==-1)
            {
                reverse(v.begin(),v.end());
            }
            ret.push_back(v);
            flag*=-1;
            
            
        }
        return ret;
    }
};




662. 二叉树最大宽度

题目解析:

根据题目分析,我们可以得出题目要我们求出二叉树的最大宽度,其中最大宽度的定义为最左和左右的非空节点之间的长度!

算法分析:

我们可以利用堆中下标的思想,进行求解,我们在堆那边有一个公式,当根节点下标为0时,左孩子下标为2*parent+1,右孩子下标为左孩子+1。当根节点为1时,左孩子下标为2*parent,右孩子仍然是左孩子+1,根据下标的特性,我们可以求出二叉树的最大宽度!

代码:

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) tmp.push_back({x->left, y * 2});
                    if(x->right) tmp.push_back({x->right, y * 2 + 1});
                    
            }
            q= tmp;
        }
        return ret;
    }

};


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

题目解析:

根据题目简单的介绍,我们可以得出题目要出的答案就是获取每层的最大值,然后进行push到结果数组中即可!

算法讲解:

还是和N叉数的层序遍历一样,我们还是需要记录的每层结点的个数,只不过本次我们需要引进一个新的变量,用于记录每层的最大值即可,我们开始将此变量置为INT_MIN即可!

代码: 

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 m=INT_MIN;
            //求出本层的结点个数!
            int len=q.size();

            for(int i=0;i<len;i++)
            {
                TreeNode*tem=q.front();
                q.pop();

                if(tem->val>m)
                {
                    m=tem->val;
                }

                //把下一层的元素压入到队列中!
                if(tem->left)
                {
                    q.push(tem->left);
                }
                if(tem->right)
                {
                    q.push(tem->right);
                }
            }
            ret.push_back(m);
        }
        
           return ret;
    }
 
};

至此,本专题总结完毕,有疑问的小伙伴可以在评论区进行讨论。

  • 17
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值