Problem Overview
LeetCode 199 — Binary Tree Right Side View — asks you to imagine standing on the right side of a binary tree and looking inward. You should return the values of the nodes you can see, ordered from top to bottom. The key insight is that from the right side, you see exactly one node per level: the rightmost node at that depth. If a level has only a left child and no right child, that left child is still visible because it is the rightmost node on its level.
This problem is a classic tree traversal exercise that tests whether you understand both BFS level-order traversal and DFS depth tracking. Both approaches solve it cleanly, but they operate on different mental models — BFS thinks in terms of levels, while DFS thinks in terms of depth. Understanding both reveals how the same problem can be modeled from different perspectives.
The constraints are straightforward: the tree can have 0 to 100 nodes, and node values are in the range [-100, 100]. The expected output is a list of integers representing the rightmost node values from top to bottom. An empty tree returns an empty list.
- Input: root of a binary tree with 0 to 100 nodes
- Output: list of values of nodes visible from the right side, top to bottom
- One visible node per level — the rightmost at that depth
- Left children with no right sibling at their depth are also visible
- Node values: integers in [-100, 100]
- Empty tree returns empty list
BFS Approach
The BFS (breadth-first search) approach processes the tree level by level using a queue. At each level, all nodes are dequeued and their children enqueued. After processing every node in a level, the last node processed is the rightmost node on that level — it is the value visible from the right side. Add that last value to the result list and continue to the next level.
This approach is the most natural match for the problem statement. The concept of "what you see from the right side" maps directly onto "the last node processed at each BFS level." There is no ambiguity and no edge case to reason through — BFS inherently processes nodes from left to right within a level, so the final node at each level is always the rightmost.
BFS runs in O(n) time since every node is visited exactly once. Space is O(w) where w is the maximum width of the tree — the largest number of nodes on any single level. For a complete binary tree this is O(n/2) at the last level, which is O(n). For a skewed tree it is O(1). In practice, the queue holds at most one full level of nodes at any point during traversal.
BFS Is the Most Intuitive Approach for Right Side View
BFS is the most intuitive approach: process each level completely and take the last element. It directly maps to the visual concept of looking from the right — each level contributes one node to your view, and BFS naturally delivers them in left-to-right order so the last one is always rightmost. No depth tracking or ordering tricks required.
BFS Implementation
The BFS implementation uses a queue initialized with the root. At each iteration, record the current queue length — this is the number of nodes on the current level. Loop that many times, dequeuing each node, enqueuing its children, and tracking the last value seen. After the inner loop, append the last value to the result.
Using a deque (collections.deque in Python) for the queue gives O(1) popleft operations, avoiding the O(n) cost of popping from the front of a plain list. In Java, ArrayDeque is the standard choice. The level-size variable is the key implementation detail — it freezes the count of nodes at the start of each level, so adding children during the same iteration does not inflate the loop count.
The total time complexity is O(n) and space complexity is O(w) for the queue, where w is the maximum width. Every node is enqueued and dequeued exactly once. The result list grows by one element per level, so its space usage is O(h) where h is the tree height — O(log n) for balanced trees, O(n) for skewed.
- 1Initialize a deque with the root node (if root is not null)
- 2While the deque is not empty:
- 3Record level_size = len(deque) — the number of nodes on this level
- 4Loop level_size times: dequeue node, enqueue left child if present, enqueue right child if present, track last_val
- 5After the inner loop, append last_val to the result list
- 6Return the result list
DFS Approach
The DFS (depth-first search) approach uses pre-order traversal but visits the right child before the left child. A depth parameter tracks the current level. When the depth equals the length of the result list, this is the first time a node at this depth has been visited — because we visit the right subtree first, this node is guaranteed to be the rightmost at that depth. Add it to the result.
The DFS approach is elegant because it avoids the queue entirely. A simple recursive function with a depth counter does all the work. The key insight is the ordering: by visiting right before left at every node, the first node encountered at each new depth is always the rightmost. Subsequent nodes at the same depth (from the left subtree) are ignored because the result list already has an entry for that depth.
DFS runs in O(n) time since every node is visited exactly once. Space is O(h) for the recursion stack where h is the tree height — O(log n) for balanced trees and O(n) for skewed trees. For trees with extreme height, the DFS approach may hit Python's recursion limit. For balanced trees, the DFS space usage is superior to BFS since tree width often exceeds height.
DFS Right-First Is Elegant — First Node at Each New Depth Is Rightmost
DFS right-first is elegant: the first node visited at each new depth is guaranteed to be the rightmost, since we explore the right subtree before the left at every level. No level-size bookkeeping needed. The condition depth == len(result) fires exactly once per level — on the first (rightmost) node encountered — and is ignored for all subsequent nodes at that depth.
Left Side View Variant
The left side view variant — returning the leftmost visible node at each depth — requires only a mirror change to each approach. In BFS, instead of recording the last node processed per level, record the first node processed per level. Since BFS processes nodes left to right within each level, the first node is always the leftmost.
In DFS, swap the child visiting order: visit the left child before the right child. The same condition depth == len(result) now fires first on the leftmost node at each depth, since the left subtree is explored first. No other logic changes.
Both variants run with identical time and space complexity to the right side view. The left side view question occasionally appears in interviews as a follow-up to verify that you understand why the approach works — not just that you memorized the code. Being able to explain and swap the direction in under a minute demonstrates genuine understanding.
- 1BFS left side view: append the first node per level instead of the last
- 2DFS left side view: visit left child before right child in the recursive call
- 3Same time complexity O(n), same space O(w) for BFS or O(h) for DFS
- 4The condition depth == len(result) still fires exactly once per level — now on the leftmost node
- 5No other code changes required — just swap the order or which element is captured
Code Walkthrough Python and Java
Python BFS: from collections import deque; def rightSideView(root): if not root: return []; result, q = [], deque([root]); while q: level_size = len(q); for i in range(level_size): node = q.popleft(); if node.left: q.append(node.left); if node.right: q.append(node.right); if i == level_size - 1: result.append(node.val); return result. Java BFS uses ArrayDeque<TreeNode> and records queue.peek() at the end of each level.
Python DFS: def rightSideView(root): result = []; def dfs(node, depth): if not node: return; if depth == len(result): result.append(node.val); dfs(node.right, depth + 1); dfs(node.left, depth + 1); dfs(root, 0); return result. Java DFS is identical in structure using a List<Integer> result and passing depth as an int parameter. Both O(n) time; BFS O(w) space, DFS O(h) space.
For interviews, BFS is the recommended answer because it is the most readable and directly maps to the problem description. DFS is a strong follow-up or alternative. Mentioning both demonstrates breadth of tree traversal knowledge. If asked for the space-optimal approach for balanced trees, DFS wins since tree height is O(log n) while width can be O(n) at the last level.
A Right-Leaning Tree Does Not Mean Only Right Children Are Visible
A right-leaning tree does not mean only right children are visible from the right side. If a node has a left child but no right child, that left child is the rightmost node on its level and is therefore visible. The right side view captures the last node at each depth — not the nodes reached via right pointers. Always think in terms of levels, not pointer directions.