问题描述:二叉树的右视图
给定一棵二叉树,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。
示例:
输入: [1,2,3,null,5,null,4]
输出: [1, 3, 4]
解释:
1 <---
/ \
2 3 <---
\ \
5 4 <---
分析:
二叉树按之字形打印
(点击蓝字走起)
1.第一眼望去和二叉树按之字形打印有点类似,不过只要每层的最后一个节点
2.想着就是还按照之字形的思路,每层的遍历结果都用一个vector存放,再把每层的最后一个节点放到结果数组中
就像这样:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<int> rightSideView(TreeNode* root) {
vector<int> ret;
if(root == nullptr)
return ret;
queue<TreeNode*> q;
q.push(root);
TreeNode* front = nullptr;
int size = 0;
while(!q.empty()){
size = q.size();
vector<int> v;
while(size--){
front = q.front();
v.push_back(front->val);
q.pop();
if(front->left)
q.push(front->left);
if(front->right)
q.push(front->right);
}
ret.push_back(v[v.size() - 1]);
}
return ret;
}
};
但是事实上,这个数组我们不用开,因为每层遍历完后,front(队首指针指的就是每层的最后一个节点),所以只需要在每层遍历完后将最后一个节点放到结果数组中即可
class Solution {
public:
vector<int> rightSideView(TreeNode* root) {
vector<int> ret;
if(root == nullptr)
return ret;
queue<TreeNode*> q;
q.push(root);
TreeNode* front = nullptr;
int size = 0;
while(!q.empty()){
size = q.size();
while(size--){
front = q.front();
q.pop();
if(front->left)
q.push(front->left);
if(front->right)
q.push(front->right);
}
ret.push_back(front->val); //每层遍历完的时候
}
return ret;
}
};
至于二叉树的左视图,我们只需要将放入结果的时机改变一下即可,思路相同
二叉树的左视图:
class Solution {
public:
vector<int> leftSideView(TreeNode* root) {
vector<int> ret;
if(root == nullptr)
return ret;
queue<TreeNode*> q;
q.push(root);
TreeNode* front = nullptr;
int size = 0;
while(!q.empty()){
size = q.size();
front = q.front(); //每层刚要遍历的时候
ret.push_back(front->val);
while(size--){
front = q.front();
q.pop();
if(front->left)
q.push(front->left);
if(front->right)
q.push(front->right);
}
}
return ret;
}
};
总结:
1.我们发现有关二叉树层序遍历的问题都需要用到队列这种数据结构
2.并且跟具体层相关的时候,我们都需要进行保存当前队列节点的数目以保证精确访问到每一具体层
版权声明:本文为Wz_still_shuai原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。