给定一棵二叉树,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。
示例:
输入: [1,2,3,null,5,null,4]
输出: [1, 3, 4]
解释:
1 <---
/ \
2 3 <---
\ \
5 4 <---
思路
主要思路就是进行层序遍历(用BFS搜),然后对当前这个结点进行判断,主要分以下几种情况:
- 如果是和上一个结点是同一层(根结点的上一个结点默认是自己),那么先加入sameLayer集合(记录同一层的所有结点的集合);
- 如果不是同一层,则说明当前结点是上一个结点的下一层,于是先更新当前层次,记录下最新的nowLayer,然后将sameLayer的最后一个元素(也就是上一层的最右侧元素)加入到答案集合answear中。之后情况sameLayer,将当前结点加入到sameLayer之中;
- 如果是当前是二叉树的最后一个结点,则需要再分两种情况判断:
1.如果当前这个最后结点和上一个结点仍是同一层,那么直接在答案集合answear里面加入当前结点即可;
2.如果不是同一层,则先需要在答案集合answear里面加入sameLayer的最后一个元素(也就是上一个结点,也即上一层的最右结点),然后再在答案集合answear里加入当前结点;
3.如果该树只有一个结点(只有一个根结点),则需要进行特判,因为此时sameLayer是空的,并不能搜到上一个结点,这个时候只要将根结点直接加入到答案集合answear里即可。 - 【注】以上三种最后一个结点的情况,执行结束之后都要return,防止程序继续跑接下来的代码。
代码
public class Solution {
public static class TreeNode{//为了方便本地调试调用内部类,我写了静态的
//实际提交时可以不写TreeNode类
int val;
TreeNode left;
TreeNode right;
TreeNode(){}
TreeNode(int val){
this.val = val;
}
TreeNode(int val, TreeNode left, TreeNode right){
this.val = val;
this.left = left;
this.right = right;
}
}
class Node{
TreeNode node;
int layer;//结点所在层数
Node(TreeNode node, int layer){
this.node = node;
this.layer = layer;
}
}
ArrayList<Node> sameLayer = new ArrayList<Node>();//存放同一层的结点
ArrayList<Integer> answear = new ArrayList<Integer>();
Queue<Node> queue = new LinkedList<Node>();
public void bfs(TreeNode root) {
Node rootNode = new Node(root, 1);
queue.offer(rootNode);
int nowLayer = 1;
while(queue.isEmpty()==false) {
Node topNode = queue.poll();//返回队首元素,并出队
if(queue.isEmpty()==true&topNode.node.left==null&topNode.node.right==null) {//如果是最后一个元素
if(topNode.layer==1) {//如果最后一个元素是根结点(只有一个结点的二叉树)
answear.add(topNode.node.val);
return;
}
if(topNode.layer==sameLayer.get(sameLayer.size()-1).layer) {//如果仍是同一层
answear.add(topNode.node.val);//直接加入当前点
return;
}
else {
answear.add(sameLayer.get(sameLayer.size()-1).node.val);//先把上一层的最后一个点加入
answear.add(topNode.node.val);//再加入当前点
return;
}
}
if(topNode.layer==nowLayer) {//如果是同一层,则加入sameLayer集合
sameLayer.add(topNode);
}
else {//如果不是,则将最后一层的元素加入最终的答案集合中,并清空sameLayer集合
nowLayer = topNode.layer;//更新当前层次
answear.add(sameLayer.get(sameLayer.size()-1).node.val);//加入同一层的最后一个点
sameLayer.removeAll(sameLayer);//清空sameLayer
sameLayer.add(topNode);//加入当前层次的第一个点
}
if(topNode.node.left!=null) {
Node lchild = new Node(topNode.node.left, topNode.layer+1);
queue.offer(lchild);
}
if(topNode.node.right!=null) {
Node rchild = new Node(topNode.node.right, topNode.layer+1);
queue.offer(rchild);
}
}
}
public List<Integer> rightSideView(TreeNode root){
if(root!=null) {//树非空则BFS搜索
bfs(root);
}
return answear;
}
}