题目 描述
给定一棵二叉树,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。
示例:
输入: [1,2,3,null,5,null,4]
输出: [1, 3, 4]
解释:
1 <---
/ \
2 3 <---
\ \
5 4 <---
思路
我的想法很简单:
层次遍历:层次遍历的具体代码借用一个队列实现(请大家自行查询)。在层次遍历过程中引入一个特殊节点“#”(代码中我用nullptr表示,详情见后面代码):用来表示这一层的遍历结束。于是我们想要的下一个数就是遇到#之前最后一个非#的节点,因为右视图肯定看到的是每层遍历的最后一个节点。(如果有类似题目,比如二叉树的左视图,那么我们完全可以使用同样的方法。修改的部门就是从右往左层次遍历,然后遍历完毕一层插入一个#)。
其他方法均和二叉树层次遍历相同。其中在遇到“#”这个节点的时候,处理有一些小小的注意点:
- 遇到#时:说明该层遍历结束,这个时候应该把这个节点从队列头front弹出来,然后在队列尾部back插入一个“#”,这时候要额外定义一个指针last用来保存上一次遇到的非#节点。
- 当把所有的二叉树节点遍历完毕之后,遇到最后一个#时,不能再按照上述情况(头front弹出一个#,尾插back一个#),这样再遍历完二叉树节点的时候容易死循环,导致一边front弹出一直back插入。所以要增加一条判断语句:判断队列的大小为1时且队列头部front就是#时立即跳出循环。
废话少说了,大家可以看代码:代码参考
vector<int> rightSideView(TreeNode* root) {
TreeNode* p=root;
deque<TreeNode*> queue1;
vector<int> res;
if(p==nullptr){
return res;
}
queue1.push_back(p);
queue1.push_back(nullptr);
TreeNode* last;
while(!queue1.empty()){
TreeNode* temp=queue1.front();
if(temp==nullptr)
{
res.push_back(last->val);
queue1.pop_front();//把空节点弹出
queue1.push_back(nullptr);
if(queue1.size()==1&&queue1.front()==nullptr){
break;
}
}
else
{
last = temp;
queue1.pop_front();
if(temp->left!=nullptr){
queue1.push_back(temp->left);
}
if(temp->right!=nullptr)
{
queue1.push_back(temp->right);
}
}
}
return res;
}