199. Binary Tree Right Side View - Detailed Explanation
Problem statement
Definition: Given the root of a binary tree, imagine yourself standing on the right side of it. The task is to return the values of the nodes you can see, ordered from top to bottom. In other words, for each level of the tree, we want the rightmost node. That is the node that would be visible when viewing the tree from the right side.
This question is an instance of the Tree Breadth First Search pattern, the technique that visits a tree one complete level at a time instead of one branch at a time. Once you recognize the pattern, the answer is short: walk every level, and keep the node you see last. The same technique covers a whole family of tree questions, which is why it appears in the recurring coding interview patterns and in this short summary of the most common LeetCode patterns.
Example 1:
Input: root = [1,2,3,null,5,null,4]
Output: [1, 3, 4]
Explanation: The tree structure is:
1 / \ 2 3 \ \ 5 4
From the right side, the visible nodes are 1 (top level), then 3 (second level, as it is to the right of 2), and then 4 (third level). Nodes 2 and 5 are hidden behind 3 and 4 when viewed from the right side.
Example 2:
Input: root = [1, null, 3]
Output: [1, 3]
Explanation: The tree has a root 1 and a right child 3. From the right side, you see 1 at the top, and 3 as the node on the next level (there is no left child to block it).
Example 3:
Input: root = [] (empty tree)
Output: []
Explanation: No nodes exist, so there is nothing to see from the right side.
Constraints
-
The number of nodes in the tree is in the range
[0, 100]. (This means the tree can be empty or have up to 100 nodes.) -
Each node's value is between
-100and100. -
The tree can be skewed (all nodes in one branch) or balanced; it can have any structure as long as it is a valid binary tree.
Hints
-
Think level by level: How can you traverse the tree one level at a time? If you process nodes level by level, like a level order traversal, you can identify the last node in each level. That last node is the one visible from the right side.
-
Use a queue for BFS: A Breadth First Search (BFS) using a queue fits level order traversal. Store the nodes of the current level in a queue, then move to the next level. The last node you encounter at each level is part of the right side view.
-
Consider depth tracking: You can also use Depth First Search (DFS) and keep track of depth. Visit the right child first, before the left child. The first node you encounter at each depth is then the rightmost node at that depth. Record it and continue the traversal.
-
One node per level: Whichever approach you pick, the result holds at most one node from each depth of the tree. Let that guide your logic, because you select exactly one node per level.
Try to sketch a small tree and simulate your approach, either BFS or DFS, to see how you would collect the visible nodes.
Multiple approaches
Approach 1: breadth first search (level order traversal)
BFS, or level order traversal, is the direct way to solve this question. Traverse the tree level by level and take the last node in each level, which is the rightmost node, for the result. This works because BFS groups nodes by their depth.
How it works: You maintain a queue for the current level of nodes. For each level:
-
Iterate through all nodes in the queue, which represents the current level.
-
Enqueue their children for the next level. Enqueue the left child first, then the right child, so the queue preserves left to right order within the level.
-
While iterating, keep track of the current node. By the time you finish a level, the current node is the last node of that level, the rightmost one. Add that node's value to the right side view list.
-
Move to the next level, meaning the children you enqueued. Continue until no nodes remain.
Why it works: In a level order traversal, nodes are visited from left to right at each level. So the last node visited at a given depth is the rightmost node at that depth. Capturing that node gives you exactly what a person standing on the right would see for that level.
When to use BFS: BFS suits this question because it hands you the level groupings directly. It is often preferable when you want to process or collect results level by level. A very wide tree, with many nodes on each level, makes BFS spend more memory on the queue. Given the constraint of 100 nodes, that cost does not matter here. BFS also returns the result in top to bottom order, which is what we need, since we append one node per level in increasing depth order.
Approach 2: depth first search (recursive)
DFS can solve the question too, by exploring one branch deeply before the others. To get the right side view with DFS, make sure you visit the right side of each level first. There are two ways to arrange that:
-
Right first DFS: Run a DFS traversal that visits a node's right child before its left child. Keep track of the current depth in the recursion. Check whether you have reached a depth you have not seen before, meaning the depth is greater than the current size of the result list. That node is then the first one encountered at that depth. Because of the right first order, it is also the rightmost node at that level, so add it to the result. Then continue the DFS into the left child. You add the visible node for each depth as you descend.
-
Left first DFS with overwrite: You can instead run a normal pre-order traversal, visiting root, then left, then right, and use an array or list indexed by depth. Update the value at each depth as you go. By the end of a level, the last value written for that depth comes from the rightmost node. This version takes more care to implement correctly, but it is another way to think about the question. Left nodes get written first, then right nodes at the same level overwrite them, which leaves the rightmost node's value in place.
Why DFS works: DFS visits every node eventually. By controlling the order of traversal, visiting the right side first, you guarantee that your first visit to a given depth lands on the rightmost node of that level. Every other node at the same depth sits to its left and is visited later. You ignore those, because you already recorded the rightmost one.
When to use DFS: DFS helps if you prefer recursion or want to avoid extra data structures such as queues. It takes a little more care to implement correctly for this specific question, but it is efficient. DFS can suit a very skewed tree, shaped like a chain, because the recursion depth equals the height of the tree. You then never hold many nodes in memory at once. Granted, in the worst case of a skewed tree, BFS and DFS both handle at most O(n) nodes in memory. DFS is also natural if you already use DFS for other computations on the same tree and want this logic in the same traversal. For clarity, though, most candidates present BFS first.
BFS versus DFS, which to choose
Both approaches have the same time complexity, since they visit each node exactly once. The choice comes down to clarity and the shape of the tree:
-
BFS is typically easier to understand for level related questions, because it deals with levels directly. If you need the result in level order, top to bottom, BFS gives you that ordering.
-
DFS requires careful handling of depth, but it runs in one pass without an explicit queue. It uses the call stack for recursion instead. If recursion depth is not a concern, and a height of at most 100 here is no concern, DFS reads well too.
-
On space, BFS may use extra space proportional to the width of the tree, which is O(n) in the queue in the worst case if one level holds n/2 nodes. DFS uses space proportional to the height of the tree for the recursion stack, which is O(n) in a skewed tree. For balanced trees, the height is smaller than the node count, so DFS may use less space. With at most 100 nodes, these differences are minor.
-
Summary: Use BFS for a direct level by level solution, where the rightmost element of each level is easy to reason about. Use DFS if you want a recursive solution and are comfortable managing the depth logic, which is often just as concise. Both produce the correct result.
Step by step walkthrough
Let us walk through Example 1, [1,2,3,null,5,null,4], using the BFS approach, to see how the right side view is determined:
The tree looks like this, with right side view nodes marked <---:
1 <--- visible / \ 2 3 <--- visible \ \ 5 4 <--- visible
We expect the output [1, 3, 4] for the right side view. Now let us simulate the BFS traversal:
-
Initialize: Start with the root in a queue.
queue = [1]. The right side view listresultis empty. Depth = 0, the root level. -
Level 0: The queue has 1 node, the root.
- Dequeue
1. It is the only node at this level, so when we finish this level,1is the last node we saw. Add its children to the queue for the next level. The children of 1 are2on the left and3on the right, so enqueue them. - End of level 0: The last node we saw was
1, so we add1toresult. - Now
result = [1]. Queue for next level:queue = [2, 3].
- Dequeue
-
Level 1: The queue has 2 nodes:
[2, 3].- Dequeue
2, the first node of this level. Enqueue its children. Node 2 has no left child, which is null, and a right child5, so enqueue5. - Next, dequeue
3. Enqueue its children. Node 3 has no left child and a right child4, so enqueue4. - End of level 1: The last node processed was
3, after2, so3is the rightmost node of this level. Add3toresult. - Now
result = [1, 3]. Queue for next level:queue = [5, 4]. Note that 5 was enqueued before 4, and both wait in the queue for the next level.
- Dequeue
-
Level 2: The queue has 2 nodes:
[5, 4].- Dequeue
5. Enqueue its children if any. Node 5 is a leaf, so there are no children to add. - Next, dequeue
4. Enqueue its children if any. Node 4 is also a leaf, so again none. - End of level 2: The last node processed in this level was
4, so4is the visible node on the right side for this level. Add4toresult. - Now
result = [1, 3, 4]. Queue for next level:queue = [], no more nodes.
- Dequeue
-
End: The queue is empty, so we have processed all levels of the tree. The
resultnow holds the right side view:[1, 3, 4], which matches the expected output.
How the BFS result grows:
- After level 0: seen
1→ right side view so far[1] - After level 1: seen
2, 3→ right side view now[1, 3], since 3 was last on that level - After level 2: seen
5, 4→ right side view now[1, 3, 4], since 4 was last on that level
Each level's last node is what we append to the result.
DFS walkthrough, in brief: Run the same example with a right first DFS. The traversal order is: visit 1 at depth 0, then 3 at depth 1 as the right child of 1, then 4 at depth 2 as the right child of 3. At that point we have seen a node at depths 0, 1 and 2, namely 1, 3 and 4. DFS then backtracks to visit the left child of 3, which does not exist, and backtracks again to 1 to visit 2 at depth 1. From 2 it visits the right child 5 at depth 2. We already recorded a node at depth 2, which was 4, so we skip 5. The collected result is still [1, 3, 4]. The right first order picks up the correct nodes without any level bookkeeping.
Python implementation
Java implementation (BFS)
Explanation: The Java solution uses a Queue<TreeNode> for BFS. We read levelSize = queue.size() to determine the number of nodes at the current level. We iterate that many times, polling from the queue and adding children to the queue. The variable currentNode is updated to the node being processed. After the loop it holds the last node of that level. We then add currentNode.val to result, which records the rightmost node of each level. The buildTree helper in main creates a binary tree from an array of Integer, where null means no child, so you can test the examples.
Both implementations use the same logic: level by level traversal, picking the last node of each level. They handle edge cases such as an empty tree, returning an empty list right away. You can run the provided main tests to verify the output for the example cases.
For a guided version of this question, with the level loop built up one step at a time, see the lesson where it is taught in Grokking the Oracle Coding Interview.
Complexity analysis
Time Complexity: Both BFS and DFS visit each node exactly once, so the time complexity is O(n), where n is the number of nodes. In Example 1, each of the 5 nodes is enqueued and dequeued once in BFS. Every node is processed a constant number of times, through a few queue operations or recursive calls, so the cost is linear in the size of the tree.
Space Complexity:
-
BFS: Uses a queue to hold at most one level of nodes at a time. In the worst case, a completely balanced tree, the last level holds about n/2 nodes, so the queue can reach O(n) in size. BFS therefore has O(n) space complexity in the worst case. On average, for a balanced tree, the space is proportional to the width of the tree. The output list adds at most O(h) more, where h is the height of the tree, which is O(n) in the worst case of a skewed tree whose height approaches n.
-
DFS: Uses recursion, or an explicit stack, which takes space proportional to the height of the tree. In the worst case of a skewed tree, shaped like a chain, the height is n, so the recursion stack is O(n). For a balanced tree the height is about O(log n), so space usage is O(log n) in that case. DFS space complexity is therefore O(h), where h is the height of the tree. The result list matches BFS at O(h), which is at most O(n).
Given the constraint of at most 100 nodes, both time and space usage stay small. The algorithms run efficiently for every allowed input size.
Common mistakes
-
Modifying the queue or list during iteration: With BFS, a classic mistake is altering the queue in the middle of iterating over it. A
for-eachloop over the queue that also adds or removes elements will disturb the iteration order. Always read the number of nodes at the current level first, for examplelevel_size = len(queue), then loop that many times to process the current level. That way you never iterate over a changing collection. -
Wrong traversal order in DFS: If your DFS visits the left child before the right child, you record left side nodes instead. To get the right side view, traverse the right subtree first. A mistake here yields a left view or a mixed view.
-
Not handling
nullproperly: Forgetting to check for null, or None, nodes leads to errors. Both BFS and DFS implementations must handle a node that lacks a left or right child. Enqueue only children that exist, and in DFS, check whether a node is null before recursing. Also handle the case where the input root itself is null, where you return an empty list. -
Confusing depth indexing: In DFS solutions that use a list indexed by depth, it is easy to get the indices wrong or to forget to increase the depth. One common bug is missing that the list
resultgrows only when you encounter a new depth for the first time. If you append for every node regardless of depth, or use the wrong condition, the logic breaks. The correct pattern is usually this: if this is the first node at this depth, add it to the result. -
Off-by-one errors: When you write the BFS loop, make sure you add the right node. Adding the first node of each level instead of the last is a common mix-up. Check that you update the rightmost node at each level and append it after processing the level.
Two of these account for most failed attempts: iterating over the queue while it changes, and the traversal order in DFS. Watch those and the rest rarely bite.
Edge cases
Consider these edge scenarios to confirm your solution handles them:
-
Empty tree: If
rootisNoneornull, the output should be an empty list. Both BFS and DFS should return right away in this case. Our implementations do that by checkingif not rootorif(root==null)at the start. -
Single node: A tree with only one node, the root, should return a list with that single value. There are no other levels to consider. Input
[1]should output[1]. -
All nodes on the left side (left-skewed tree): For example, a tree that is a straight line going left:
1 / 2 / 3Every node here is a left child, yet from the right side you see all of them, because each node is the only node on its level. Nothing stands to the right of it at the same depth. The output is therefore
[1, 2, 3]. Make sure your logic does not assume that a missing right child means the left child goes unrecorded. In BFS, the left child ends up as the last node of that level when no node follows it. In a right first DFS, you reach that left child as the only node at its depth once the right child is absent. Since it is the first node encountered at that depth, it is added. -
All nodes on the right side (right-skewed tree): Take a tree that is a straight line to the right, such as
1 -> 3 -> 5 -> 7. The right side view is all of those nodes,[1,3,5,7]. We are looking at the tree from the right, and every node aligns. Both BFS and DFS handle this directly, since each level holds one node that is also the rightmost. -
Mixed skewed tree: A tree where some nodes have only one child. For example:
1 \ 2 / 3Here root 1 has a right child 2, and 2 has a left child 3. The levels are
[1],[2]and[3]. The right side view is[1, 2, 3]. At the third level the node is a left child of 2, but nothing stands to its right at that level, since 2 has no right child, so it becomes visible. Make sure your logic does not skip a left child's value when it is in fact visible. -
Wide tree: A tree with several nodes on one level, to confirm the code picks the rightmost one. The point is to test that you select the correct node among several at one level:
10 / \ 6 15 / \ / \ 4 8 12 20 \ 14The right view is
[10, 15, 20, 14]. Each level's rightmost node is chosen: 10 from level 0, 15 from level 1, 20 from level 2, and 14 from level 3. -
Our implementations handle these scenarios because they rely on the structure of levels and depths, not on a particular shape. Still, running through a couple of these edge cases, mentally or in code, is worth the minute it takes.
Alternative variations and related problems
This question asks for one particular view of a binary tree, the right side. Similar concepts and variations follow from it:
-
Left side view of a binary tree: This mirrors the right side view. Instead of the rightmost nodes, you collect the leftmost node of each level, which is what you see from the left side of the tree. The approach is almost identical. In DFS you traverse the left child before the right child, and in BFS you take the first node of each level instead of the last. It is a good variation to try after the right side view.
-
Top view and bottom view of a binary tree: These are more advanced variations. The top view is what you see looking down from above the tree, which is the highest node at each horizontal distance. The bottom view looks from below, giving the lowest node at each horizontal distance. Solving these requires tracking horizontal position and a different traversal strategy, often a BFS with column indices. Interviewers ask them too, but they need more than a plain level order.
-
Boundary traversal of a binary tree: This asks you to print the boundary of the tree, meaning the left boundary, the leaves, and the right boundary. It is another way to list the visible nodes from outside, and it combines multiple sides.
-
Populating next right pointers in each node: LeetCode 116 and 117 ask you to connect each node to its immediate right neighbor at the same level, rather than print the right view. They use the same BFS level traversal idea. Both handle nodes level by level and deal with the notion of a right neighbor. If BFS felt natural here, those two make a good follow-up.
-
Zigzag level order traversal: LeetCode 103 alternates the direction of traversal at each level, left to right and then right to left. It is not a view question, but it is a related traversal that BFS handles well, sometimes with a deque for cheap appends at either end.
Working through that whole family in order is faster than tackling them one at a time. The level order technique behind this question is taught, along with the other patterns these questions share, in Grokking the Coding Interview.

GET YOUR FREE
Coding Questions Catalog

$99

$197

$72