Start learning free

LESSON 441 OF 569 · BINARY TREES

Binary Tree Right Side View in Java: Level-Order BFS

Practice O(n) Read the full explanation

Given the root of a binary tree, imagine yourself standing on its right side. Return the values of the nodes you can see, ordered from top to bottom.

From the right you see exactly one node on each level: the rightmost node of that level, the last one when you read the level from left to right. It can belong to the left subtree, when the right subtree doesn't reach that deep. An empty tree shows nothing.

The trees below are written in level order (top to bottom, left to right), with null for a missing child.

 

Example 1:

    1
   / \
  2   3
   \   \
    5   4

Input: root = [1,2,3,null,5,null,4]
Output: [1,3,4]
Explanation: The first level is just 1. On the second level, 3 hides 2. On the third level, 4 hides 5.

Example 2:

      1
     / \
    2   3
   /
  4

Input: root = [1,2,3,4]
Output: [1,3,4]
Explanation: The third level has only 4. It is in the left subtree, but nothing stands to its right, so you see it.

Example 3:

Input: root = []
Output: []
Explanation: An empty tree has no levels, so you see no nodes.

 

Constraints:

  • The number of nodes in the tree is in the range [0, 100].
  • -100 <= Node.val <= 100
  • Values may repeat.

Note:

The tutorial walks the tree level by level with a queue. The queue starts with the root. At the start of each round it holds exactly one level: count its nodes, take them out one by one from the front, and put each node's children (left, then right) at the back, where they wait for the next round. The last node taken out in a round is the rightmost node of its level: that is the one you see.

Each node enters and leaves the queue once, so the time is O(n) for a tree of n nodes. The queue holds at most about two levels at a time, which is O(n) extra space in the worst case.

STEP 1 OF 11
    Ctrl + Enter to check

    JAVA · BINARY TREES

    Binary Tree Right Side View in Java, explained

    Problem overview

    The method rightSideView receives the root of a binary tree and returns a List<Integer> with the values you would see standing on the tree's right side, from the top level down. From the right you see exactly one node per level: the rightmost one. That node is not always a right child. When the right subtree is shallower than the left one, the node you see on a deep level belongs to the left subtree.

    Take the tree [1,2,3,null,5,null,4]. Level 0 is just 1. On level 1, node 3 hides node 2. On level 2, node 4 hides node 5. The answer is [1, 3, 4]. For [1,2,3,4] the third level holds only node 4, which hangs under 2, and nothing stands to its right, so it is visible: the answer is again [1, 3, 4]. An empty tree gives an empty list.

    The lesson provides the TreeNode class (it appears in a comment in the starter code), with the fields val, left and right and a constructor that takes the value.

    Approach: walk the tree one level at a time

    A tempting shortcut is to follow right pointers from the root and collect what you meet. It fails as soon as a right branch ends before a left one does. Run on [1,2,3,4], that shortcut returns [1, 3] instead of [1, 3, 4], and on [1,2,null,3,null,4] (a chain that only goes left) it returns [1] instead of [1, 2, 3, 4].

    The reliable idea is to treat the question as "what is the last node of each level?" and visit the tree level by level with a breadth-first search (BFS). A queue makes this natural: nodes leave from the front in the order they arrived, and each node's children join at the back. If the queue holds exactly one level at the start of a round, then after that round the children of that level, and nothing else, are waiting for the next round.

    Inside a round, the nodes come out from left to right, because the left child is always added before the right one. So the last node taken out in a round is the rightmost node of its level, and that is the one to record.

    Step by step

    1. Create result, an ArrayList that will receive one value per level.
    2. Return it right away for an empty tree. The queue needs a first node to start from, and an empty tree shows nothing.
    3. Create the queue as an ArrayDeque, declared as a Deque<TreeNode>, and add the root. add puts a node at the back; poll takes one from the front.
    4. Loop while the queue is not empty. One pass of this loop handles one whole level.
    5. Store queue.size() in levelSize. At this moment the queue holds exactly one level. The number must be saved first, because the size changes as children are added during the round. Reading queue.size() in the loop condition instead would mix the next level into the current one.
    6. Visit the level with a for loop that counts i from 0 up to levelSize.
    7. Take the next node with queue.poll().
    8. Record the last one. When i == levelSize - 1, the node is the last of its level, so add node.val to result.
    9. Queue the left child if it exists. It waits behind the rest of the current level.
    10. Queue the right child if it exists, right after the left one, which keeps every level in left-to-right order.
    11. Return result after the loops.

    The solution in Java

    class Solution {
        public List<Integer> rightSideView(TreeNode root) {
            List<Integer> result = new ArrayList<>();
            if (root == null) {
                return result;
            }
            Deque<TreeNode> queue = new ArrayDeque<>();
            queue.add(root);
            while (!queue.isEmpty()) {
                int levelSize = queue.size();
                for (int i = 0; i < levelSize; i++) {
                    TreeNode node = queue.poll();
                    if (i == levelSize - 1) {
                        result.add(node.val);
                    }
                    if (node.left != null) {
                        queue.add(node.left);
                    }
                    if (node.right != null) {
                        queue.add(node.right);
                    }
                }
            }
            return result;
        }
    }

    A few Java details are worth knowing. Deque<TreeNode> is the interface type, and ArrayDeque is the class behind it; both ends are fast. poll() returns null when the queue is empty, but it is only called while the loop knows that levelSize nodes are waiting, so node is never null there. The list holds Integer objects, and result.add(node.val) boxes the int for you.

    The children are checked against null before they are added. Without those checks a missing child would enter the queue as null, and the next node.left would throw a NullPointerException.

    Complexity

    Every node enters the queue once and leaves it once, with constant work in between, so the time is O(n) for a tree of n nodes. The queue holds at most about two levels at once. For a wide tree, such as a complete tree whose last level has about half the nodes, that is O(n) extra space. The result list is the output and is not counted.

    Edge cases and common mistakes

    • Only following right children. It misses nodes that are visible because the right side is shorter, as the runs above show.
    • Using the first node of each level. That gives the left side view instead.
    • Not saving the level size. The queue grows while you work, so a loop bounded by the live queue.size() does not stop at the end of the level.
    • Forgetting the empty tree. queue.add(null) on an ArrayDeque throws, so the early return matters.
    • Repeated values. The tree may hold equal values; the method records nodes by position, so duplicates cause no trouble.

    Testing

    These inputs were run against the solution above, with the trees written in level order:

    TreeResult
    [1,2,3,null,5,null,4][1, 3, 4]
    [1,2,3,4][1, 3, 4]
    [][]
    [1,null,2,null,3][1, 2, 3]
    [1,2,null,3,null,4][1, 2, 3, 4]
    [7][7]
    Keep going with Java500+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free