队列 与 宽度优先算法(BFS)是解决很多算法问题的常见工具。
BFS通过逐层遍历图或树的节点来寻找解决问题的最短路径或最短步骤。使用队列可以很好地支持BFS算法的实现。
下面是一个使用队列和宽度优先算法解决问题的一般步骤:
使用队列和宽度优先算法可以解决许多问题,例如迷宫问题、最短路径问题、连通性问题等。具体的实现方式可能因问题而异,但基本思路是相似的。
思路
解法:队列,宽度优先搜索
代码
vector<vector<int>> levelOrder(Node* root) {
vector<vector<int>> ret; // 最终结果
queue<Node*> q; // 用队列记录节点
// 将本层元素放入队列,提取出值后出队,将子节点入队
if(root) q.push(root);
else return ret;
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); // tmp记录该层节点值
for(Node* child : t->children) // 当前节点的子节点入队
{
if(child) // 不为空
q.push(child);
}
}
ret.push_back(tmp); // 更新结果
}
return ret;
}
思路
代码
vector<vector<int>> zigzagLevelOrder(TreeNode* root) {
// 锯齿形层序遍历:偶数层逆序遍历,奇数层正常遍历
vector<vector<int>> ret;
queue<TreeNode*> q;
if(!root) return ret;
else q.push(root);
int level = 1; // 根据flag判断是否逆序
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;
}
思路
代码
int widthOfBinaryTree(TreeNode* root) {
// 队列(数组)存储节点及其下标(补全null节点后的下标)
vector<pair<TreeNode*, unsigned int>> q;
// q.push_back(make_pair<nullptr, 0>);
if(!root) return 0;
else q.push_back({root, 1}); // // 根节点从1下标开始
unsigned int ret = 0; // 最终结果
while(q.size())
{
// 计算本层宽度
auto [node1, x1] = q[0]; // 提取一个pair类型
auto [node2, x2] = q.back();
ret = max(ret, x2 - x1 + 1);
vector<pair<TreeNode*, unsigned int>> tmp; // tmp存储下一层节点信息,覆盖q
for(auto& [node, x] : q)
{
// 左孩子下标:2x 右孩子下标:2x+1
if(node->left) tmp.push_back({node->left, 2*x});
if(node->right) tmp.push_back({node->right, 2*x + 1});
}
q = tmp;
}
return ret;
}
思路
代码
vector<int> largestValues(TreeNode* root) {
vector<int> ret; // 结果数组
queue<TreeNode*> q; // 队列用于层序遍历
if(!root) return ret;
else q.push(root);
while(!q.empty())
{
int sz = q.size();
int maxVal = INT_MIN; // 用于比较节点大小
while(sz--)
{
auto t = q.front(); // 提取当前节点
q.pop();
maxVal = max(maxVal, t->val);
if(t->left) q.push(t->left);
if(t->right) q.push(t->right);
}
ret.push_back(maxVal);
}
return ret;
}