Binary Tree Right Side View
MediumGiven the root of a binary tree, imagine yourself standing on the right side of it, return the values of the nodes you can see ordered from top to bottom.
Example
Input: root = [1,2,3,null,5,null,4]
Output: [1,3,4]
Explanation: From the right side, you can see nodes 1, 3, and 4.
Explanation
The most efficient approach to solve this problem is using BFS level-order traversal with a queue. The key insight is that for each level, the last node processed (the rightmost one) is the node visible from the right side of the tree.
We process the tree level by level using the following steps:
- Initialize a
queuewith the root node - While the queue is not empty, get the current
level_size(number of nodes at this level) - Process all nodes at the current level; the last node processed in each level is the "right side" view
- For each node, add its children to the queue (left first, then right)
This approach works because by processing all nodes at each level from left to right, the last node we encounter at each level is always the rightmost visible node from the right side.
Idea Map
Initialize queue = deque([root])
While queue is not empty
1. level_size = len(queue)
2. For i in range(level_size):
Dequeue node
If last node in level → add to result
Enqueue node.left, node.right
Complexity Analysis
Time Complexity
O(n) - We visit every node in the tree exactly once.
Space Complexity
O(n) - The queue holds at most n/2 nodes (the widest level of the tree).
Code
def rightSideView(root):
Defines the function `rightSideView` which takes the `root` of a binary tree and returns the values visible from the right side.
if not root:
Base case: if the tree is empty (root is None), there are no nodes to see from the right side.
return []
Return an empty list immediately for an empty tree.
result = []
Initialize the result list that will hold the rightmost node value from each level.
queue = deque([root])
Create a deque (double-ended queue) initialized with the root node to start BFS.
while queue:
Continue processing while there are still nodes in the queue (levels left to visit).
level_size = len(queue)
Capture the number of nodes at the current level before processing. This is the key to separating levels.
for i in range(level_size):
Loop exactly `level_size` times to process only nodes belonging to the current level. We use `i` to track position.
node = queue.popleft()
Dequeue the front node from the queue (FIFO order ensures left-to-right processing).
if i == level_size - 1:
Check if this is the last node in the current level. The last node is the rightmost one visible from the right side.
result.append(node.val)
Add the rightmost node's value to the result list. This node is visible from the right side.
if node.left:
Check if the current node has a left child before enqueuing it.
queue.append(node.left)
Add the left child to the queue so it will be processed in the next level.
if node.right:
Check if the current node has a right child before enqueuing it.
queue.append(node.right)
Add the right child to the queue so it will be processed in the next level.
return result
Return the list of rightmost node values, one per level, representing the right side view.
public List<Integer> rightSideView(TreeNode root) {
Defines the method that takes a TreeNode root and returns a list of integer values visible from the right side.
List<Integer> result = new ArrayList<>();
Initialize the result list that will hold the rightmost node value from each level.
if (root == null) return result;
Base case: if the tree is empty, return the empty result list immediately.
Queue<TreeNode> queue = new LinkedList<>();
Create a LinkedList-based Queue to perform BFS traversal.
queue.offer(root);
Add the root node to the queue to begin the BFS traversal.
while (!queue.isEmpty()) {
Continue processing while there are nodes in the queue (levels left to visit).
int levelSize = queue.size();
Capture the number of nodes at the current level. This is essential for separating levels.
for (int i = 0; i < levelSize; i++) {
Loop exactly `levelSize` times to process only nodes belonging to the current level.
TreeNode node = queue.poll();
Dequeue the front node from the queue (FIFO order ensures left-to-right processing).
if (i == levelSize - 1) {
Check if this is the last node in the current level — the rightmost one visible from the right side.
result.add(node.val);
Add the rightmost node's value to the result list.
}
End of the if block that checks for the last node in the level.
if (node.left != null) queue.offer(node.left);
If the left child exists, add it to the queue for processing in the next level.
if (node.right != null) queue.offer(node.right);
If the right child exists, add it to the queue for processing in the next level.
}
End of the for loop that processes all nodes at the current level.
}
End of the while loop.
return result;
Return the list of rightmost node values representing the right side view.
}
End of the method.
vector<int> rightSideView(TreeNode* root) {
Defines the function that takes a pointer to the root TreeNode and returns a vector of integers visible from the right side.
vector<int> result;
Initialize the result vector that will hold the rightmost node value from each level.
if (!root) return result;
Base case: if the tree is empty (null pointer), return the empty result immediately.
queue<TreeNode*> q;
Create a queue of TreeNode pointers to perform BFS traversal.
q.push(root);
Push the root node onto the queue to begin the BFS traversal.
while (!q.empty()) {
Continue processing while there are nodes in the queue (levels left to visit).
int levelSize = q.size();
Capture the number of nodes at the current level. This is essential for separating levels.
for (int i = 0; i < levelSize; i++) {
Loop exactly `levelSize` times to process only nodes belonging to the current level.
TreeNode* node = q.front();
Get a pointer to the front node of the queue (peek without removing).
q.pop();
Remove the front node from the queue (in C++, front() and pop() are separate operations).
if (i == levelSize - 1) {
Check if this is the last node in the current level — the rightmost one visible from the right side.
result.push_back(node->val);
Add the rightmost node's value to the result vector.
}
End of the if block that checks for the last node in the level.
if (node->left) q.push(node->left);
If the left child exists, push it onto the queue for processing in the next level.
if (node->right) q.push(node->right);
If the right child exists, push it onto the queue for processing in the next level.
}
End of the for loop that processes all nodes at the current level.
}
End of the while loop.
return result;
Return the right side view as a vector of integers.
}
End of the function.
Edge Cases & Common Mistakes
Assuming the rightmost child is always the answer
In a skewed left tree like [1,2,null,3], node 3 is the right side view at level 2 even though it's a left child. You must process the full level.
Empty tree (null root)
Always check for null root before starting BFS. Return empty list for null input.
Single node tree
Returns [root.val] correctly since it's the only node at level 0, making it the rightmost by default.
Related Problems
When Should You Use BFS vs DFS?
BFS and DFS are two fundamental graph traversal strategies. BFS explores nodes level by level using a queue, while DFS goes as deep as possible using a stack. Understanding when to use each is key to solving tree and graph problems efficiently.
Learn more about BFS vs DFS →Disclaimer: This problem is for educational purposes. Practice the 'Binary Tree Right Side View' problem on LeetCode.