【优选算法】队列+宽搜(BFS)

目录

一、N 叉树的层序遍历

题目描述:

思路讲解:

本题可以使用队列来解决,定义一个队列qu,定义一个vector<vector<int>> ans来记录答案,定义一个vector<int> tmp来记录每一层节点,将树中的根节点放入到队列中,得到当前层有多少个节点,将这些节点从队列中取出,放入到tmp中并将这些节点的子节点添加到队列中,每当tmp中取到了一层的节点就添加的ans中,然后再清空,重复这个操作直到队列中为空为止,再将ans返回即可。

在做本道题时,我个人感觉题目并没有将null存入到某个节点的子节点数组中,所以大家遍历节点子数组时需要注意遍历方式。

编写代码:

cpp 复制代码
/*
// Definition for a Node.
class Node {
public:
    int val;
    vector<Node*> children;

    Node() {}

    Node(int _val) {
        val = _val;
    }

    Node(int _val, vector<Node*> _children) {
        val = _val;
        children = _children;
    }
};
*/

class Solution {
public:
    vector<vector<int>> levelOrder(Node* root) {
        queue<Node*> qu;
        vector<vector<int>> ans;
        qu.push(root);

        if(root == nullptr)
            return ans;

        vector<int> tmp;

        while(!qu.empty())
        {
            int count = qu.size();
            while(count--)
            {
                Node* node = qu.front();
                qu.pop();
                tmp.push_back(node->val);
                // for(auto ptr : node->children)
                // {
                //     qu.push(ptr);
                // }
                for(int i = 0 ; i < node->children.size() ; i++)
                {
                    qu.push(node->children[i]);
                }
            }
            ans.push_back(tmp);
            tmp.clear();
        }
        return ans;
    }
};

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

题目描述:

思路讲解:

本题与上一题的思路一致,就是层序遍历树,与上一题的区别就是本题遍历一层是正序,下一层就是逆序,下一层就是正序一直循环,本题需要定义一个变量来标记哪些层需要逆序,并将这些节点逆转并存入,本题就不做过多讲解了。

编写代码:

cpp 复制代码
/**
 * 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:
    vector<vector<int>> zigzagLevelOrder(TreeNode* root) {
        queue<TreeNode*> qu;
        vector<vector<int>> ans;
        qu.push(root);

        if(root == nullptr)
            return ans;

        vector<int> tmp;

        int row = 0;

        while(!qu.empty())
        {
            int count = qu.size();
            while(count--)
            {
                TreeNode* node = qu.front();
                qu.pop();
                tmp.push_back(node->val);

                if(node->left) qu.push(node->left);
                if(node->right) qu.push(node->right);
            }

            if(row % 2 == 0)
                ans.push_back(tmp);
            else 
            {
                reverse(tmp.begin(),tmp.end());
                ans.push_back(tmp);
            }
            
            tmp.clear();
            row++;
        }
        return ans;
    }
};

三、二叉树最大宽度

题目描述:

思路讲解:

本题有一个暴力解法,就是将每一层的节点都存储到一个数组中,无论是空节点还是非空节点,然后遍历每一层节点找到相差最远的两节点的宽度,最终得到本棵树中的最大宽度,但是有这么一种情况就是每一层的节点数很少,使这颗树很深,最终导致下面树的一层节点个数太多无法被存储,所以只有使用另一种方法来解决。

使用数组存储二叉树的特性,给二叉树的每一个节点标记上编号,定义一个队列,队列中存储的是当前节点的地址和当前节点的编号,那么我们就可以通过队列来得到每一层的节点,将每一层节点中离得最远的两个节点编号相减得到当前层的节点最大宽度,通过比较每一层的节点最大宽度,得到这棵树的最大节点宽度。

需要注意的是,我们得到的节点编号可能会溢出,但是只要两个节点编号相差不超过一个类型的范围,那么两个节点的编号相减就是正确的,例如int类型的取值范围为-2^31^~2^31^-1,只要两个值相差不超过2^32^,那么这两个值相减得到的差值就是正常的,题目中提到了答案是在32位带符号整数范围内,所以两个节点编号一定相差不超过一个int类型的范围,也就是2^32^,所以这两个节点编号的差值就是正确的,而本题使用int记录编号时,会溢出报错,所以这里需要使用无符号整形来存储这节点的编号。

编写代码:

cpp 复制代码
/**
 * 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) {
        queue<pair<TreeNode*,size_t>> qu;
        qu.push(make_pair(root,0));

        size_t MaxLen = 0;
        while(!qu.empty())
        {
            size_t left = qu.front().second , right = qu.back().second ;
            if(MaxLen < right - left + 1) MaxLen = right - left + 1;

            int count = qu.size();
            while(count--)
            {
                pair<TreeNode*,int> node = qu.front();
                qu.pop();

                if(node.first->left) 
                    qu.push(make_pair(node.first->left,(size_t)2*(node.second)+1));
                if(node.first->right) 
                    qu.push(make_pair(node.first->right,(size_t)2*(node.second)+2));
            }
        }
        return MaxLen;
    }
};

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

题目描述:

思路讲解:

本题与第一题的思路有些相似,本题也需要遍历每一层,并得到每一层中最大的数存入到数组中即可,使用队列即可遍历得到每一层的节点,本题也不过多做讲解。

编写代码:

cpp 复制代码
/**
 * 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:
    vector<int> largestValues(TreeNode* root) {
        queue<TreeNode*> qu;
        vector<int> ans;
        qu.push(root);

        if(root == nullptr)
            return ans;

        while(!qu.empty())
        {
            int rowMax = INT_MIN;
            int count = qu.size();

            while(count--)
            {
                TreeNode* node = qu.front();
                qu.pop();
                if(node->val > rowMax)
                    rowMax = node->val;

                if(node->left) qu.push(node->left);
                if(node->right) qu.push(node->right);
            }

            ans.push_back(rowMax);
        }
        return ans;
    }
};

结尾

如果有什么建议和疑问,或是有什么错误,大家可以在评论区中提出。

希望大家以后也能和我一起进步!!🌹🌹

如果这篇文章对你有用的话,希望大家给一个三连支持一下!!🌹🌹

相关推荐
爱学习的橙子羊2 分钟前
673.最长递增子序列
算法·动态规划
掘根9 分钟前
动态规划五——回文串问题
算法·动态规划
阳光开朗_大男孩儿10 分钟前
动态规划模式
算法·动态规划·代理模式
执着的小火车12 分钟前
【2024华为OD-E卷-100分-火星文计算】(题目+思路+Java&C++&Python解析)
java·数据结构·c++·算法·华为od·华为
矮油0_o22 分钟前
30天开发操作系统 第 11 天 --制作窗口
c语言·开发语言·c++·系统架构
MinBadGuy22 分钟前
【GeekBand】C++设计模式笔记20_Composite_组合模式
c++·设计模式
万事大吉CC24 分钟前
697: Edit Distance
c++
刀客12327 分钟前
C++ 基础思维导图(一)
开发语言·c++
_DCG_1 小时前
c++之左值引用 右值引用 万能引用
java·开发语言·c++
强里秋千墙外道1 小时前
【QT】实现RestFul接口
c++