Algorithm

Binary Tree Left/Right Side View

Trees Pattern

Binary Tree Left/Right Side View

Stand to the right of the tree and look at it horizontally: at each depth you see exactly one node, the one furthest right on that level. Return those values ordered from the top of the tree downward. The left side view is the mirror question, taking the leftmost node of each level. The result has exactly one entry per level, and an empty tree returns an empty list.

CONSTRAINTS
  • The number of nodes in the tree is in the range [0, 100]
  • -100 <= Node.val <= 100
  • Exactly one value per level, ordered top to bottom
  • Visibility is by level position, not by which child slot a node occupies
EXAMPLE 1
Input: root = [1,2,3,null,5,null,4], right side view
Output: [1,3,4]
One value per depth: 1 at the top, then 3, then 4. The node 5 is hidden behind 4, which sits further right on the same level.
EXAMPLE 2
Input: root = [1,2,3,4], right side view
Output: [1,3,4]
At the bottom level only 4 exists, and it is a *left* child. It is visible because nothing else shares its level — being rightmost is about position on the level, not about being a right child.
EXAMPLE 3
Input: root = [1,2], right side view
Output: [1,2]
The root's right side is empty, so its left child is the only node on that level and therefore the visible one.
EXAMPLE 4
Input: root = [1,2,3,4,null,null,5], left side view
Output: [1,2,4]
Looking from the other side takes the first node of each level instead of the last. 5 is hidden behind 4.
If a node is a left child but nothing sits to its right on that level, is it visible?
Yes. Visibility depends on being last on the level, not on being someone's right child — the second example turns on exactly this.
Is there always exactly one value per level?
Yes, since every non-empty level has a rightmost node. The output length therefore equals the tree's height.
Does the left side view need different code?
Only in which node of each level you keep — the first instead of the last. Everything else is identical.
Can this be solved depth-first?
Yes: visit right before left and record the first node seen at each new depth. It gives the same answer in O(H) space instead of O(W), which is better on wide trees.

Looking at a tree from the side, the node you see at a given depth is the one furthest right on that level — everything else on that level is hidden behind it. So the answer is one node per level, and the only question is which.

The first instinct is usually wrong in an instructive way: follow the right children down from the root. That fails as soon as the right spine ends early. If the root's right child has no children of its own but the left subtree runs three levels deeper, those deeper levels are still visible — the rightmost node there simply comes from the left side of the tree. Visibility is a property of position on a level, not of which pointer slot a node occupies.

The traversal already knows the order

Once the answer is phrased as "the last node of each level," the level-by-level walk from Binary Tree Level Order Traversal delivers it directly. Within a level, the queue hands nodes over strictly left to right, so the final node of the frozen level_size iterations is the rightmost one. Record that, discard the rest.

python
if root is None: return []
out, queue = [], deque([root])
while queue:
    n = len(queue)                      # frozen level size, exactly as before
    for i in range(n):
        node = queue.popleft()
        if i == n - 1:                  # the last node of this level is the visible one
            out.append(node.val)
        if node.left:  queue.append(node.left)
        if node.right: queue.append(node.right)
return out

Nothing about the traversal changed — only the rule for what gets recorded. The left side view is the same code with i == 0.

Crucial Notechildren must still be enqueued left then right, even for the right side view. It is tempting to reverse the enqueue order and take the first node instead, and while that happens to work, it is the reasoning to be careful with: as in Zigzag, the enqueue order determines the left-to-right meaning of the entire level below. If you flip it, you must flip your selection rule at every level too, and the two flips are easy to get out of step. Leave the traversal alone and change only the selection.
The depth-first alternative, and why it works

There is a second solution worth knowing, because it costs different memory. Walk the tree depth-first but visit the right child before the left, carrying the current depth as a parameter. Then the first node ever reached at any given depth is the rightmost node of that depth.

The argument: visiting right-first means that among all nodes at a fixed depth, the walk reaches them in right-to-left order — at every branching point above them, the right-hand descendants are explored before the left-hand ones. So the first arrival at a new depth is the rightmost node there. Record a node only when the recorded list is shorter than the depth we have reached, which is exactly the test for "this depth has not been seen yet."

python
out = []
def walk(node, depth):
    if node is None: return
    if depth == len(out):        # first time we reach this depth
        out.append(node.val)     # so this is the rightmost node here
    walk(node.right, depth + 1)  # right FIRST
    walk(node.left,  depth + 1)
walk(root, 0)
Worked example:root 1, children 2 and 3; 2 has a right child 5; 3 has a right child 4
Breadth-first:
- Level 0: n = 1. Pull 1 at i = 0 = n - 1 → record 1. Enqueue 2, 3.
- Level 1: n = 2. Pull 2 at i = 0, skip it, enqueue 5. Pull 3 at i = 1 = n - 1 → record 3, enqueue 4.
- Level 2: n = 2. Pull 5, skip. Pull 4 at i = 1 → record 4.
- Result: [1, 3, 4]. Node 5 was visited and discarded, since 4 stands to its right.

Now the second example, root 1 with children 2 and 3, where 2 has a left child 4. At level 2 the queue holds only 4, so n = 1 and 4 is at index n - 1 — recorded, despite being a left child and despite the right subtree having nothing at that depth. This is exactly the case the naive "walk the right spine" idea gets wrong.

Cost, and the takeaway

Both solutions visit every node once: O(N) time. Their memory differs — the queue version costs O(W) for the widest level, the depth-first version O(H) for the recursion stack. On a wide bushy tree, prefer depth-first; on a deep chain, prefer the queue. That is the same trade laid out in Level Order Traversal, and this problem is a clean place to see both sides of it in working code.

The habit to build: when a problem asks for "the visible" or "the first" or "the extreme" something per level, the traversal is almost certainly untouched — only the selection rule changes. Level Order records everything, Zigzag reorders the recording, Side View filters it down to one. Recognising which of the three slots a new problem touches — traversal, ordering, or selection — is usually the entire solution.

Interactive Strategy Visualization

Perspective Analysis

Simulate Left vs. Right visibility

1234567
Perspective Engine
Initialize DFS for right view...

Algorithm Rules

  • Depth Tracking: Use a Level variable to track vertical position.
  • Visibility Rule: First node visited at any depth is part of the view.
  • Priority Search: Prioritize Right child to see Right Side.
Memory Strategy
If level == result.size(), it's the first time we've reached this depth.
O(N) Time · O(W) Space Last Node Per Level (BFS)
O(N) Time · O(H) Space Right-First DFS With Depth