21. Binary Tree Right Side View
Given a binary tree, return the nodes visible when viewing it from the right side.
I would use breadth-first search with a deque. I process the tree one level at a time from left to right. At each level, I append the value of the last node removed from the queue because that node is visible from the right side. I add each node’s left child before its right child. Every node is enqueued and dequeued once, so the time complexity is O(n). The auxiliary space is O(w), where w is the maximum tree width.
See the Code while reading this explanation.
The input is the root of a binary tree. We must return one node value from each level, representing what is visible from the right side. Breadth-first search fits this problem because it naturally visits the tree level by level. By processing each level from left to right, the last node processed at that level is the visible node.
- What input sizes, value ranges, and edge cases should the solution handle?
- What output should be returned for empty, invalid, or duplicate input?
- Should I prioritize execution time or memory use, and may I use the standard library?
The input is a reference to the root of a binary tree. The tree is not assumed to be a binary search tree.
The output is a list of node values. It contains one visible value from every level, ordered from the root level to the deepest level.
For the displayed tree, the levels are [1], [2, 3], [4, 5, 7], and [6]. The returned right-side view is [1, 3, 7, 6].
I use breadth-first search, also called BFS. BFS processes the tree one level at a time.
A deque stores nodes that are waiting to be processed. It supports efficient removal from the front and insertion at the back.
The central rule is that nodes in each level are processed from left to right. Therefore, the final node removed at that level is the rightmost visible node.
I create an empty list named result.
If root is None, the tree is empty, so I return result immediately.
Otherwise, I place the root in the deque. For the example, the initial queue is [1], and the initial result is [].
At level 0, the queue is [1]. The level size is 1. I remove node 1. It is the last node in this level, so I append 1. I then add its left child 2 and right child 3. The result is [1].
At level 1, the queue is [2, 3]. The level size is 2. I remove node 2 and add its children 4 and 5. I then remove node 3. It is the last node in the level, so I append 3. I add its right child 7. The result is [1, 3].
At level 2, the queue is [4, 5, 7]. The level size is 3. I process node 4, then node 5, then node 7. Node 5 adds its left child 6. Node 7 is the last node in this level, so I append 7. The result is [1, 3, 7].
At level 3, the queue is [6]. The level size is 1. I remove node 6. It is the last node in the level, so I append 6. The result becomes [1, 3, 7, 6].
The queue is now empty, so the traversal stops and the function returns [1, 3, 7, 6].
At the start of each outer-loop iteration, the queue contains the nodes of the next level in left-to-right order.
The inner loop removes exactly those nodes. Because the final removed node is the rightmost node in that level, appending its value records the correct visible value.
Repeating this for every level produces the complete right-side view from top to bottom.
The outer while loop continues while the deque contains nodes.
At the start of a level, level_size stores the current queue length. This separates the current level from children added for the next level.
The inner loop removes exactly level_size nodes. When i equals level_size - 1, the current node is the final node in that level, so its value is appended to result.
The code adds the left child before the right child. This preserves left-to-right processing order.
The time complexity is O(n), where n is the number of nodes. Every node is added to the deque once and removed once.
The auxiliary space complexity is O(w), where w is the maximum number of nodes stored in the queue at one level.
An empty tree returns []. A tree with one node returns [root.val]. In a left-skewed or right-skewed tree, every node appears in the result because each level contains one node.
The key insight is to process the binary tree level by level with BFS. A deque stores the nodes waiting to be visited. At the beginning of each level, its current length gives the number of nodes that belong to that level. The algorithm removes those nodes from left to right and records the value of the final removed node. The invariant is that the queue presents each current level in left-to-right order, so its last processed node is exactly the node visible from the right side.
from collections import deque
from typing import List, Optional
class TreeNode:
def __init__(
self,
val: int = 0,
left: Optional["TreeNode"] = None,
right: Optional["TreeNode"] = None,
) -> None:
# Store this node's value and child references.
self.val = val
self.left = left
self.right = right
class Solution:
def rightSideView(self, root: Optional[TreeNode]) -> List[int]:
# Store the rightmost visible value from each level.
result: List[int] = []
# An empty tree has no visible nodes.
if not root:
return result
# Start breadth-first search with the root node.
q = deque([root])
# Process one complete tree level per outer-loop iteration.
while q:
# Save the current level size before adding its children.
level_size = len(q)
# Remove all nodes that belong to the current level.
for i in range(level_size):
node = q.popleft()
# The final node processed from left to right is visible.
if i == level_size - 1:
result.append(node.val)
# Add children from left to right for the next level.
if node.left:
q.append(node.left)
if node.right:
q.append(node.right)
# Return the visible values from top to bottom.
return result
if __name__ == "__main__":
# Build the verified example tree:
# 1
# / \
# 2 3
# / \ \
# 4 5 7
# /
# 6
root = TreeNode(1)
root.left = TreeNode(2)
root.right = TreeNode(3)
root.left.left = TreeNode(4)
root.left.right = TreeNode(5)
root.right.right = TreeNode(7)
root.left.right.left = TreeNode(6)
answer = Solution().rightSideView(root)
print(answer) # [1, 3, 7, 6]The time complexity is O(n), where n is the total number of nodes. Each node enters the deque once and leaves it once. The auxiliary space complexity is O(w), where w is the maximum number of nodes stored in the queue at one level. A wide tree may therefore use more queue memory than a narrow tree.
Level-order traversal is useful when software must process hierarchical data one depth at a time. Examples include displaying organization levels, reading category trees by layer, creating summaries for each tree depth, and finding the first or last item visible at every level.
This question tests whether a candidate recognizes level-order tree traversal and chooses an efficient queue structure. It also checks whether the candidate can separate one level from the next, maintain a clear invariant, and preserve the correct child insertion order. The interviewer is also evaluating edge-case handling, clean Python code, and accurate reasoning about O(n) time and O(w) auxiliary space.
A candidate may record the first node at each level, which produces the left-side view. Another mistake is to let the inner loop use a changing queue length instead of saving level_size first. Some candidates add right children before left children but still record the final node, which changes the meaning of the invariant. Using list.pop(0) instead of deque.popleft() makes front removal slower. It is also incorrect to assume that the input follows binary search tree ordering.
State the invariant before writing code: because each level is processed from left to right, the last node removed from that level is the node visible from the right side.









