二叉树的右视图

题目

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

示例

输入: [1,2,3,null,5,null,4]
输出: [1, 3, 4]
解释:

   1            <---
 /   \
2     3         <---
 \     \
  5     4       <---

ps: 可千万不要想成一直获取右节点就好了,下图这种情况也需要考虑。

   1            <---
 /   \
2     3         <---
 \     \
  5     4       <---
   \ 
    6           <---

这时候你需要输出[1, 3, 4, 6]

解题

思路

第一想法,使用递归解决,优先递归右节点,新建集合,当这一层级还没有节点的时候,就把该节点设置为这一层级的右视图节点,放入集合。

复杂度分析
这种解法,树中的所有元素都会被遍历到,时间复杂度为O(n)

极限状况下,二叉树的高度会达到节点的个数,空间复杂度为O(n)

代码

/**
 * 二叉树的右视图(递归法,dfs方法)
 *
 * @author yanghang
 */
public class RightSideView {


    public static void main(String[] args) {
        TreeNode root = new TreeNode(1);
        TreeNode t1 = new TreeNode(2);
        TreeNode t2 = new TreeNode(3);
        TreeNode t3 = new TreeNode(4);
        TreeNode t4 = new TreeNode(5);
        TreeNode t5 = new TreeNode(6);
        TreeNode t6 = new TreeNode(7);
        root.left = t1;
        root.right = t2;
        t1.left = t3;
        t1.right = t4;
        t2.left = t5;
        t2.right = t6;
        System.err.println(rightSideView2(root));
    }

    public static List<Integer> rightSideView(TreeNode root) {
        if (Objects.isNull(root)) {
            return new ArrayList<>();
        }
        List<Integer> nums = new ArrayList<>();
        Deque<TreeNode> firstDeque = new LinkedList<>();
        Deque<TreeNode> secondDeque = new LinkedList<>();
        firstDeque.add(root);
        while (!firstDeque.isEmpty()) {
            pollData(nums, firstDeque, secondDeque);
            pollData(nums, secondDeque, firstDeque);
        }
        return nums;
    }

    private static void pollData(List<Integer> nums, Deque<TreeNode> firstDeque, Deque<TreeNode> secondDeque) {
        int index = 0;
        while (!firstDeque.isEmpty()) {
            TreeNode poll = firstDeque.poll();
            if (index == 0) {
                nums.add(poll.val);
            }
            if (Objects.nonNull(poll.right)) {
                secondDeque.add(poll.right);
            }
            if (Objects.nonNull(poll.left)) {
                secondDeque.add(poll.left);
            }
            index++;
        }
    }

    public static List<Integer> rightSideView2(TreeNode root) {
        List<Integer> res = new ArrayList<>();
        if (Objects.isNull(root)) {
            return res;
        }
        int level = 0;
        recursion(res, root, level);
        return res;
    }

    public static void recursion(List<Integer> res, TreeNode root, int level) {
        if (Objects.isNull(root)) {
            return;
        }
        if (res.size() == level) {
            res.add(root.val);
        }
        recursion(res, root.right, level + 1);
        recursion(res, root.left, level + 1);
    }
}