二叉树刷题篇(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叉树的确需要一段时间来熟悉,今天就到这里吧。这几道题让人久违的有了做题的感觉(做题家实锤了),会一道等于会五道,争取以后也能够有类似这样举一反三,融会贯通的体验吧~
