二叉树刷题篇(3)层序遍历
给你一个二叉树,请你返回其按 层序遍历 得到的节点值。 (即逐层地,从左到右访问所有节点)。
https://leetcode-cn.com/problems/binary-tree-level-order-traversal/
这个没什么好说的,用队列存储节点,然后用size存储大小,这样可以保证每次处理的数据是自己想要的数据。
代码如下。
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> ans;
queue<TreeNode*> que;
if(root!=NULL) que.push(root);
while(!que.empty()){
int size=que.size();
vector<int> layer;
for(int i=0;i<size;i++){
TreeNode* cur=que.front();
layer.push_back(cur->val);
que.pop();
if(cur->left!=NULL) que.push(cur->left);
if(cur->right!=NULL) que.push(cur->right);
}
ans.push_back(layer);
}
return ans;
}
};
解决完这道题,我们来看下一位选手:二叉树层序遍历II。emmmm,小兄弟,你确定不是来送人头的?在第一题的基础上,只需简单的修改即可。
给定一个二叉树,返回其节点值自底向上的层序遍历。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)
https://leetcode-cn.com/problems/binary-tree-level-order-traversal-ii/submissions/
给出一段神秘代码就可以解决这道题,reverse(ans.begin(),ans.end());你猜猜加在哪?
再来看三号选手,199.二叉树的右视图。
给定一棵二叉树,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。
https://leetcode-cn.com/problems/binary-tree-right-side-view/
首先一定要避免一个思维误区,即简单地认为一直向着右边遍历下去就可以。(不会吧不会吧,不会真有人这么傻吧……比如我自己哈哈哈)
最好想的思路应该是将层序遍历每一层的最后一个数作为答案输出。实现方法应该也很简单,在层序遍历的代码中加入判断,当每层循环到size次时,才将节点数值push到向量中。
class Solution {
public:
vector<int> rightSideView(TreeNode* root) {
queue<TreeNode*> que;
vector<int> ans;
if(root!=NULL) que.push(root);
while(!que.empty()){
int size=que.size();
for(int i=0;i<size;i++){
TreeNode* cur=que.front();
if(i==size-1) ans.push_back(cur->val);
que.pop();
if(cur->left!=NULL) que.push(cur->left);
if(cur->right!=NULL) que.push(cur->right);
}
}
return ans;
}
};
直接贴代码……一次成功!下一题!637.二叉树的层平均值。
给定一个非空二叉树, 返回一个由每层节点平均值组成的数组。
https://leetcode-cn.com/problems/average-of-levels-in-binary-tree/
怎么说呢,只要二叉树的层序遍历熟练掌握,这些题真的都很简单,直接上代码。与之前的不同就是需要在i==size-1时计算下平均值,这里需要注意,因为我们把之前的值已经pop掉了,所以需要一个额外的变量sum来记录总的值。sum/size就是我们想要的平均值。
当然,这里还有一种方法是在for循环后进行平均值的计算,这样显然会更直观,更简洁。
class Solution {
public:
vector<double> averageOfLevels(TreeNode* root) {
queue<TreeNode*> que;
vector<double> ans;
if(root!=NULL) que.push(root);
while(!que.empty()){
int size=que.size();
double sum=0;
for(int i=0;i<size;i++){
TreeNode* cur=que.front();
sum+=cur->val;
if(i==size-1) ans.push_back(sum/size);
que.pop();
if(cur->left!=NULL) que.push(cur->left);
if(cur->right!=NULL) que.push(cur->right);
}
}
return ans;
}
};
最后是五娃,429.N叉树的层序遍历。
给定一个 N 叉树,返回其节点值的层序遍历。(即从左到右,逐层遍历)。
https://leetcode-cn.com/problems/n-ary-tree-level-order-traversal/
看来五娃稍稍不一样,实际上不同的地方也只在于N叉树与二叉树的不同,其实我对N叉树的结构也不是很熟悉,为了避免出错,我们还是先看一下Leetcode官方给出的N叉树的定义。
/*
Definition for a Node.
class Node {
public:
int val;
children;
{}
_val) {
val = _val;
}
_val, vector<Node*> _children) {
val = _val;
children = _children;
}
};
*/
看来N叉树和二叉树区别并不大(这不是废话吗~),只是存储其孩子的容器变成了vector,事不宜迟,直接开写代码。
class Solution {
public:
vector<vector<int>> levelOrder(Node* root) {
queue<Node*> que;
if (root != NULL) que.push(root);
vector<vector<int>> result;
while (!que.empty()) {
int size = que.size();
vector<int> vec;
for (int i = 0; i < size; i++) {
Node* node = que.front();
que.pop();
vec.push_back(node->val);
for (int i = 0; i < node->children.size(); i++) { // 将节点孩子加入队列
if (node->children[i]) que.push(node->children[i]);
}
}
result.push_back(vec);
}
return result;
}
};
依然是没有什么太大的难度,但第一次接触N叉树的确需要一段时间来熟悉,今天就到这里吧。这几道题让人久违的有了做题的感觉(做题家实锤了),会一道等于会五道,争取以后也能够有类似这样举一反三,融会贯通的体验吧~