LeetCode——199 二叉树的右视图(JAVA)

给定一棵二叉树,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。

示例:

输入: [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;
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值