leetcode_199:Binary Tree Right Side View

这个题目其实没啥说的,就是层次遍历,每次都取那一层的最后一个就行。只是编码过程中有一些边界条件需要注意,再有就是这种需要保存上一层状态的题目,一般是需要两个队列的,来轮流保存每层的节点,代码如下:

    public List<Integer> rightSideView(TreeNode root) {
        List<Integer> result = new ArrayList<>();
        if (root == null)
            return result;
        if (root.left == null && root.right == null) {
            result.add(root.val);
            return result;
        }
        Queue<TreeNode> queue1 = new LinkedList<>();
        Queue<TreeNode> queue2 = new LinkedList<>();
        //先将根节点加入到队列中
        queue1.add(root);
        while (!queue1.isEmpty() || !queue2.isEmpty()) {
            TreeNode finalCur = null;	//记录一层最后的节点
            while (!queue1.isEmpty()) {
                TreeNode curNode = queue1.remove();
                if (curNode.left != null)
                    queue2.add(curNode.left);
                if (curNode.right != null)
                    queue2.add(curNode.right);
                finalCur = curNode;
            }
            //如果finalCur不为空说明queue1保存的那层遍历了,所以要取出那一层最后一个
            if (finalCur != null)
                result.add(finalCur.val);
            //重置,让它在queue2中继续寻找最后一个
            finalCur = null;
            while (!queue2.isEmpty()) {
                TreeNode curNode = queue2.remove();
                if (curNode.left != null)
                    queue1.add(curNode.left);
                if (curNode.right != null)
                    queue1.add(curNode.right);
                finalCur = curNode;
            }
            //不为空说明queue2保存的那层也遍历了,取出那一层最后一个
            if (finalCur != null)
                result.add(finalCur.val);
        }
        return result;
    }

2020.2.8

更新来了,我写的代码真傻,原来真的是自己看自己原来写的代码怎么看怎么恶心。

一、广度优先遍历

还是上面那个思路,但是简单多了

    public List<Integer> rightSideView(TreeNode root) {
        if (root == null) {
            return new ArrayList<>();
        }
        Queue<TreeNode> queue = new LinkedList<>();
        queue.add(root);
        List<Integer> ret = new ArrayList<>();
        while (!queue.isEmpty()) {
            int size = queue.size();  //记录下当前这一层的节点数
            for (int i = 0; i < size; i++) {
                TreeNode node = queue.poll();
                if (i == size - 1) {  //到最后一个结点时就可以加到结果中,而不需要两个队列轮流存储
                    ret.add(node.val);
                }
                if (node.left != null) { //把弹出队列的左子树和右子树都加到队列中
                    queue.add(node.left);
                }
                if (node.right !=null) {
                    queue.add(node.right);
                }
            }
        }
        return ret;
    }

二、深度优先遍历

深度优先遍历其实也不难,因为我们肯定是访问的最右边的那一层,所以我们参考先序递归遍历的思路

  • 先访问根节点,然后它是右视图的一个结点
  • 然后访问右子树
  • 紧接着访问左子树

但是要注意的是,这个过程中我们在判断一个结点是不是右视图的时候,要增加一个参数level,代表我们当前访问到了第几层,如果result中的元素数目和当前层数相同,说明当前层中已经有一个右视图结点了,所以我们就不要添加了。而我们怎么保证这个右视图一定是我们想要的右视图呢,是因为我们遍历的顺序是先遍历右子树

先访问结点的右子树,然后再访问结点

class Solution {
    public List<Integer> rightSideView(TreeNode root) {
        List<Integer> result = new ArrayList<>();
        helper(root, result, 1);
        return result;
    }

    private void helper(TreeNode root, List<Integer> result, int curLevel) {
        if (root == null)
            return;
        if (result.size() < curLevel) //只有当前层的结点还未加入到result时,才把它加进去
            result.add(root.val);
        helper(root.right, result, curLevel+1); //递归遍历右子树,level要+1
        helper(root.left, result, curLevel+1);  //递归遍历左子树,level要+1
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值