队列➕宽搜(BFS)算法的应用
《递归、回溯、宽搜》--------基础知识
第一题:
题解思路: 总体就是在出队之前,将他的孩子入队
1、先入根节点;
2、再取对头节点;
3、再出队,再将孩子节点再次入队;
4、如此循环反复;
题解代码:
/*
// 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) {
vector<vector<int>> ret;
if (root == nullptr)
return ret;
queue<Node*> q;
q.push(root);
while (q.size()) {
// 出队的次数
int size = q.size();
vector<int> tmp;
// 出队操作
for (int i = 0; i < size; i++) {
// 取队顶;
Node* t = q.front();
// 插入到数组中;
tmp.push_back(t->val);
// 出队
q.pop();
// 每出一个就要将他的孩子入队
for (auto& child : t->children) {
if (child != nullptr)
q.push(child);
}
}
// 走到这就表示一层走完了;
ret.push_back(tmp);
}
return ret;
}
};
第二题:
题解思路:
1、在上面的层序遍历的基础上,增加一个判断每层是正序还是逆序的过程
题解代码:
/**
* 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;
if (root == nullptr)
return ret;
queue<TreeNode*> q;
bool flag = true;
q.push(root);
while (q.size()) {
// 出队的次数
int size = q.size();
vector<int> tmp;
// 出队的操作;
for (int i = 0; i < size; i++) {
auto 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 (flag) {
ret.push_back(tmp);
flag = false;
} else {
reverse(tmp.begin(), tmp.end());
ret.push_back(tmp);
flag = true;
}
}
return ret;
}
};
第三题:
题解思路:
1、给每个节点主观的编码(可以是1序,也可以是0序);
2、用数组模拟队列;
3、用每层的第一个和最后一个节点的编码相减得到每层的长度;
4、更新每层的长度ret = max(ret,newret);
5、最后遍历完后,就得最长的长度是多少了;
值得注意点细节:
1、用pair<node* ,unsigned int>组合;
2、不能用int 而应该用unsigned int,因为数据量太大可能会造成Int 的溢出;相减会得到一个负数,所以应该采用无符整形,尽管溢出,相减还是会得到一个正确的值;
3、关于数组出队的问题,若是采用的是数组头删的方式,就会导致效率过低,这里我们应该采用新的数组覆盖旧的数组的方式;
解题代码:
/**
* 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) {
// 数组模拟的队列
vector<pair<TreeNode*, unsigned int>> q;
unsigned int ret = 0;
q.push_back({root, 1});
// 进行遍历每层的操作;
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;
}
};