灵神【基础算法精讲】视频的个人笔记。
层序遍历:从上往下,从左往右遍历。
视频例题
102. 二叉树的层序遍历
可以用两个数组,一个存当前层数的节点,另一个存下一层的节点。
用队列实现更加方便。
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
if(!root) return {};
vector<vector<int>> ans;
queue<TreeNode*> q;
q.push(root);
while(!q.empty()) {
vector<int> vals; //一层的值
int len = q.size();
for (int i = 0; i < len; ++i) { //遍历当前层
TreeNode* t = q.front();
q.pop();
vals.emplace_back(t->val);
if(t->left) q.push(t->left);
if(t->right) q.push(t->right);
}
ans.emplace_back(vals);
}
return ans;
}
};
103. 二叉树的锯齿形层序遍历
思路: 这题在层序遍历的基础上,多了一个条件:交替进行正序和倒序。 那就需要一个标记,是否需要倒序
- 需要就逆转该层的vals数组
- 否则不变
class Solution {
public:
vector<vector<int>> zigzagLevelOrder(TreeNode* root) {
if(!root) return {};
vector<vector<int>> ans;
int flag = false; //是否需要倒序
queue<TreeNode*> q;
q.push(root);
while(!q.empty()) {
vector<int> vals;
int len = q.size();
for (int i = 0; i < len; ++i) {
TreeNode* t = q.front();
q.pop();
vals.emplace_back(t->val);
if(t->left) q.push(t->left);
if(t->right) q.push(t->right);
}
if(flag)
reverse(vals.begin(), vals.end()); //倒序
ans.emplace_back(vals);
flag = !flag;
}
return ans;
}
};
513. 找树左下角的值
思路: 按照层序遍历的顺序,从左到右,最后一个节点就是最底层最右边的节点。 如果反过来,从右到左层序遍历,那么最后一个节点就是最底层最左边的节点了。
由于不需要每一层的值,就不需要for (int i = 0; i < len; ++i)来遍历当前层,直接去掉。
class Solution {
public:
int findBottomLeftValue(TreeNode* root) {
if(!root) return 0;
queue<TreeNode*> q;
q.push(root);
TreeNode* t;
while(!q.empty()) {
t = q.front();
q.pop();
if(t->right) q.push(t->right);
if(t->left) q.push(t->left);
}
return t->val; //最后一个节点
}
};
课后作业
104. 二叉树的最大深度
思路: 遍历完一层,深度+1
class Solution {
public:
int maxDepth(TreeNode* root) {
if(!root) return 0;
queue<TreeNode*> q;
q.push(root);
int depth = 0;
while(!q.empty()) {
int len = q.size();
for (int i = 0; i < len; ++i) { //遍历当前层
TreeNode* t = q.front();
q.pop();
if(t->left) q.push(t->left);
if(t->right) q.push(t->right);
}
depth++;
}
return depth;
}
};
111. 二叉树的最小深度
思路: 层序遍历是从上往下,遇到的第一个叶子节点肯定是深度最小的。
每一个节点都判断是否叶子节点,是就直接返回。
class Solution {
public:
int minDepth(TreeNode* root) {
if(!root) return 0;
queue<TreeNode*> q;
q.push(root);
int cnt = 0; //层数
while(!q.empty()) {
int len = q.size();
cnt++;
for (int i = 0; i < len; ++i) {
auto t = q.front();
q.pop();
if(t->left == nullptr && t->right == nullptr) //叶子节点,直接返回
return cnt;
if(t->left) q.push(t->left);
if(t->right) q.push(t->right);
}
}
return 0;
}
};
199.二叉树的右视图
思路: 每一层只要最后一个节点。
class Solution {
public:
vector<int> rightSideView(TreeNode* root) {
if(!root) return {};
vector<int> ans;
queue<TreeNode*> q;
q.push(root);
while(!q.empty()) {
int len = q.size();
TreeNode* t;
for (int i = 0; i < len; ++i) {
t = q.front();
q.pop();
if(t->left) q.push(t->left);
if(t->right) q.push(t->right);
}
ans.emplace_back(t->val); //该层最后一个节点
}
return ans;
}
};