Editorial
Core insight
Binary Tree Right Side View · Tree Traversal Patterns (DFS & BFS)
Core Insight for Binary Tree Right Side View
The key intuition for solving LeetCode 199 is that the "right side view" is equivalent to the last node encountered in a standard left-to-right level order traversal for each level.
When we perform a BFS, we visit nodes in increasing order of their distance from the root (depth 0, depth 1, depth 2, etc.). Within each depth, nodes are typically visited from left to right. Therefore, if we track the traversal level by level, the last node processed in the current level's iteration is physically the rightmost node at that depth.
Visual Description: Imagine the BFS process using a queue.
- Level 0: The queue contains
[root]. We process the list. The last (and only) item isroot. This is the visible node for depth 0. - Level 1: We add the children of
root. The queue might contain[left_child, right_child]. We iterate through them. The loop ends onright_child. This is the visible node for depth 1. - Level 2: If
right_childhas no children butleft_childhas children, the queue for the next level will contain nodes only from the left side of the tree. The last node in this sequence is still the rightmost valid node for that depth.
By enforcing the constraint that we process the entire level before moving to the next, we can deterministically pick the correct node without complex backtracking.
Deep dive
Full breakdown
Full reasoning, pitfalls, and implementation flow
LeetCode 199: Binary Tree Right Side View Solution & Explanation
Problem Overview
TL;DR: Perform a Level Order Traversal (BFS) and record the value of the last node visited at each depth level to construct the view from the right side.
The Binary Tree Right Side View problem asks us to determine which nodes are visible when looking at a binary tree from the right side. This essentially means selecting the rightmost node at every depth of the tree. If the right branch is missing or shorter than the left branch, the nodes from the left branch at deeper levels become visible.
This is a popular interview question that tests your ability to traverse tree data structures and manipulate level-based logic. It is designated as LeetCode 199.
Brute Force Approach for Binary Tree Right Side View
A common naive approach (and a frequent mistake) is to assume the "right side view" simply consists of the nodes found by traversing only the right child pointers starting from the root.
Naive Algorithm Description
- Start at the
root. - Add the current node to the result list.
- Move to
node.right. - Repeat until the current node is null.
Pseudo-code
function naiveRightView(root):
result = []
current = root
while current is not null:
result.add(current.val)
current = current.right
return resultComplexity Analysis
- Time Complexity: , where is the height of the tree (specifically the length of the rightmost path).
- Space Complexity: auxiliary space (excluding result storage).
Why It Fails
This approach fails the correctness test. It assumes the right side view is blocked solely by the immediate right children. However, a binary tree can have a left subtree that is significantly deeper than the right subtree. In such cases, the nodes in the left subtree extend below the right subtree and become visible from the right side. The naive approach completely ignores the left subtree, leading to an incomplete answer.
Algorithm Strategy: Tree BFS - Level Order Traversal
To implement the optimal solution using the BFS pattern:
- Queue Initialization: Use a queue to facilitate Breadth-First Search. Initialize it with the
rootnode (if not null). - Level-by-Level Processing: Use a standard BFS
whileloop. Inside this loop, determine the number of nodes currently in the queue (levelSize). This count represents exactly one horizontal level of the tree. - Inner Loop: Iterate exactly
levelSizetimes to process all nodes at the current depth.- Dequeue the current node.
- Add its children (left, then right) to the queue for the next level.
- Capture Rightmost Node: Inside the inner loop, check if the current index is the last index of the level (i.e.,
i == levelSize - 1). If true, add this node's value to the result list. - Termination: The algorithm terminates when the queue is empty, meaning all levels have been processed.
Execution Flow
- Check Edge Case: If
rootisnull, return an empty list immediately. - Setup: Create an empty list
result. Create a queueqand pushrootinto it. - Traverse: While
qis not empty:- Capture the current size of the queue:
n = q.size(). - Iterate
ifrom0ton - 1:- Pop
nodefrom the front ofq. - Identification Step: If
iequalsn - 1, appendnode.valtoresult. - If
node.leftexists, push it toq. - If
node.rightexists, push it toq.
- Pop
- Capture the current size of the queue:
- Return: Return
result.
Proof of Correctness
The correctness relies on the FIFO (First-In-First-Out) property of the queue and the order of insertion.
- Invariant: At the start of the outer loop, the queue contains all nodes at depth and only nodes at depth .
- Ordering: We insert children in Left Right order. Consequently, for any depth , nodes are stored in the queue ordered from left to right.
- Selection: By iterating through the exact number of nodes present at the start of the level, we ensure we process the entire depth . The last node processed in this iteration is the one that was inserted last for this level, which corresponds to the rightmost physical position in the tree.
- Thus, the algorithm correctly captures exactly one node per level, which is the rightmost one.
Pattern Reuse Notes
The Tree BFS - Level Order Traversal pattern is highly reusable. Understanding how to iterate level-by-level using a queue size snapshot allows you to solve several related LeetCode problems:
- LeetCode 102: Binary Tree Level Order Traversal: The base pattern; simply collects all nodes instead of just the last one.
- LeetCode 103: Binary Tree Zigzag Level Order Traversal: Adds a direction flag to the standard BFS to reverse order every other level.
- LeetCode 515: Find Largest Value in Each Tree Row: Instead of picking the last node, you track the maximum value seen in the inner loop.
- LeetCode 1161: Maximum Level Sum of a Binary Tree: Sums the values in the inner loop to find the level with the highest aggregate value.
Feynman coach · Before you peek at the code
Can you explain the core insight in your own words?
If you can explain it before reading code, you’re far more likely to recall it under interview pressure.
Reference Implementation
C++ Solution for LeetCode 199
1#include <vector>
2#include <queue>
3
4using namespace std;
5
6/**
7 * Definition for a binary tree node.
8 * struct TreeNode {
9 * int val;
10 * TreeNode *left;
11 * TreeNode *right;
12 * TreeNode() : val(0), left(nullptr), right(nullptr) {}
13 * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
14 * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
15 * };
16 */
17class Solution {
18public:
19 vector<int> rightSideView(TreeNode* root) {
20 vector<int> result;
21 if (!root) return result;
22
23 queue<TreeNode*> q;
24 q.push(root);
25
26 while (!q.empty()) {
27 int levelSize = q.size();
28
29 for (int i = 0; i < levelSize; ++i) {
30 TreeNode* currentNode = q.front();
31 q.pop();
32
33 // If it's the last node in the current level, add to result
34 if (i == levelSize - 1) {
35 result.push_back(currentNode->val);
36 }
37
38 // Add children to queue for the next level
39 if (currentNode->left) q.push(currentNode->left);
40 if (currentNode->right) q.push(currentNode->right);
41 }
42 }
43
44 return result;
45 }
46};Java Solution for LeetCode 199
1import java.util.ArrayList;
2import java.util.LinkedList;
3import java.util.List;
4import java.util.Queue;
5
6/**
7 * Definition for a binary tree node.
8 * public class TreeNode {
9 * int val;
10 * TreeNode left;
11 * TreeNode right;
12 * TreeNode() {}
13 * TreeNode(int val) { this.val = val; }
14 * TreeNode(int val, TreeNode left, TreeNode right) {
15 * this.val = val;
16 * this.left = left;
17 * this.right = right;
18 * }
19 * }
20 */
21class Solution {
22 public List<Integer> rightSideView(TreeNode root) {
23 List<Integer> result = new ArrayList<>();
24 if (root == null) return result;
25
26 Queue<TreeNode> queue = new LinkedList<>();
27 queue.offer(root);
28
29 while (!queue.isEmpty()) {
30 int levelSize = queue.size();
31
32 for (int i = 0; i < levelSize; i++) {
33 TreeNode currentNode = queue.poll();
34
35 // If this is the last node in the current level, record it
36 if (i == levelSize - 1) {
37 result.add(currentNode.val);
38 }
39
40 if (currentNode.left != null) queue.offer(currentNode.left);
41 if (currentNode.right != null) queue.offer(currentNode.right);
42 }
43 }
44
45 return result;
46 }
47}Python Solution for LeetCode 199
1from collections import deque
2from typing import Optional, List
3
4# Definition for a binary tree node.
5# class TreeNode:
6# def __init__(self, val=0, left=None, right=None):
7# self.val = val
8# self.left = left
9# self.right = right
10
11class Solution:
12 def rightSideView(self, root: Optional[TreeNode]) -> List[int]:
13 result = []
14 if not root:
15 return result
16
17 queue = deque([root])
18
19 while queue:
20 level_size = len(queue)
21
22 for i in range(level_size):
23 node = queue.popleft()
24
25 # If this is the last node in the current level, add to result
26 if i == level_size - 1:
27 result.append(node.val)
28
29 if node.left:
30 queue.append(node.left)
31 if node.right:
32 queue.append(node.right)
33
34 return result