C++算法:队列与BFS

队列与BFS

1.N叉树的层序遍历

使用BFS,即宽度优先搜索。把节点放入队列中,当节点出队列时让其孩子节点入队列,记录每层节点数量。

cpp 复制代码
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.empty())
        {
            vector<int> v;
            int len = q.size(); //当前层节点数量
            for (int i = 0;i < len;i++)
            {
                Node* p = q.front();
                q.pop();
                v.push_back(p->val);

                for (Node* child : p->children)//下一层节点入队列
                    if (child != nullptr)
                        q.push(child);
            }
            ret.push_back(v);
        }
        return ret;
    }
};

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

与上一题相似,锯齿形层序遍历时,可以照常从左到右遍历,把第一层记为level=1,每偶数层时逆序数组即可。也可以使用别的方法,只要能在偶数层逆序即可。

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)
    {
        vector<vector<int>> ret;
        queue<TreeNode*> q;
        int flag = 1;  // 规定flag<0小于时逆序数组。
        if (root == nullptr)
            return ret;
        q.push(root);
        while (!q.empty())
        {
            int len = q.size();
            vector<int> v;
            for (int i = 0;i < len;i++)
            {
                TreeNode* p = q.front();
                q.pop();
                v.push_back(p->val);

                if (p->left)
                    q.push(p->left);
                if (p->right)
                    q.push(p->right);
            }
            if (flag < 0) //判断是否逆序数组
                reverse(v.begin(), v.end());
            flag *= -1;
            ret.push_back(v);
        }
        return ret;
    }
};

3.二叉树最大宽度

根据题意,如果直接按照前面题目的模板,会出现超出内存限制的情况。如下图所示,3000个节点分别位于两侧,中间全为空节点。

此时可以考虑树的顺序存储。即给树的每个节点从左到右,从上到下编号,如果从1开始编号,某个节点下标为x,则它的孩子节点为2x和2x+1。依旧使用循环+队列的模板,非空节点入队列,队列元素应使用pair类型,记录节点及其下标,每次循环取队头和队尾的下标做差再加1,即可求出一层的宽度。

题目保证最终的宽度在32位带符号的整数范围内,如果用int做差返回的宽度错误,用unsigned int则能够正确返回宽度。

cpp 复制代码
class Solution {
public:
    int widthOfBinaryTree(TreeNode* root)
    {
        queue<pair<TreeNode*, unsigned int>> q;
        unsigned int ret = 0;
        q.push({ root,1 });
        while (!q.empty())
        {
            auto e1 = q.front();
            auto e2 = q.back();
            ret = max(ret, e2.second - e1.second + 1);
            size_t len = q.size();
            for (int i = 0;i < len;i++)
            {
                auto p = q.front();
                q.pop();
                if (p.first->left)
                    q.push({ p.first->left,p.second * 2 });
                if (p.first->right)
                    q.push({ p.first->right,p.second * 2 + 1 });
            }
        }
        return ret;
    }
};

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

与1、2题类似。只需用一个变量在遍历时记录最大值即可。

cpp 复制代码
class Solution {
public:
    vector<int> largestValues(TreeNode* root)
    {
        queue<TreeNode*> q;
        vector<int> ret;
        if (root == nullptr)
            return ret;
        q.push(root);
        while (!q.empty())
        {
            int Max = INT_MIN;
            size_t len = q.size();
            for (int i = 0;i < len;i++)
            {
                TreeNode* p = q.front();
                q.pop();
                if (Max < p->val)
                    Max = p->val;

                if (p->left)
                    q.push(p->left);
                if (p->right)
                    q.push(p->right);
            }
            ret.push_back(Max);
        }
        return ret;
    }
};
相关推荐
曦樂~10 小时前
Cpp面筋
c语言·c++
道尔柯南10 小时前
C++ string 类详解:从常用接口到深拷贝,彻底掌握字符串处理
android·java·c++
Dream it possible!13 小时前
LeetCode 面试经典 150_多维动态规划_交错字符串(97_C++_中等)
算法·leetcode·面试·动态规划
心抵鹊13 小时前
算法之双指针系列(一)
算法·leetcode
十二13 小时前
【洛谷题解】P1083 [NOIP 2012 提高组] 借教室(二分答案 + 差分)
数据结构·c++·算法·蓝桥杯
小此方14 小时前
[算法实战论:动态规划]回文串问题的dp解法,回文串问题的母题,以及以此为基础的派生题
算法·动态规划
Pniubi15 小时前
力扣560.和为k的子数组
算法·leetcode·职场和发展
D e re k ZH15 小时前
C++ 从零入门(一):基础语法与程序结构
数据结构·c++·算法
Pniubi16 小时前
力扣438.找到字符串中所有字母异位词
算法·leetcode·职场和发展
zjxtxdy17 小时前
C++面向对象程序开发-类与对象
开发语言·c++