Find Bottom Left Tree Value: BFS Level-by-Level
Given the root of a binary tree, return the leftmost value in the last row of the tree. This is LeetCode 513: Find Bottom Left Tree Value. The problem guarantees the tree has at least one node, so you never need to handle an empty input.
The problem
You are given a binary tree and need to find the value of the bottom-left node. "Bottom" means the deepest level, and "left" means the leftmost node at that level. If the deepest level has only one node, that node is the answer regardless of whether it is a left or right child.
For example, given root = [2, 1, 3, null, null, 5, 4], the tree looks like this:
The deepest level is Level 2, which contains nodes 5 and 4. The leftmost value at that level is 5, so the answer is 5.
The approach
The cleanest way to solve this is BFS with a right-to-left twist. In a standard BFS, you enqueue left children before right children. Here, you flip the order: enqueue the right child first, then the left child. This means at every level, the left side gets processed last. When the queue is fully drained, the very last node you dequeued is the bottom-left node.
No need to track level boundaries. No need to snapshot the queue size. Just run BFS, keep overwriting a result variable with each node you dequeue, and return it at the end.
Enqueue right before left. The last node BFS visits is the bottom-left value. This single reversal eliminates all level-tracking bookkeeping.
Step-by-step walkthrough
Trace BFS right-to-left through the tree [2, 1, 3, null, null, 5, 4]. At each step, watch the queue and the current result value. Because right children enter the queue before left children, the leftmost node at the deepest level is always processed last.
Step 1: Initialize. Push root into the queue.
Queue: [2]
Result so far: 2
Set result to root's value. About to process the queue.
Step 2: Dequeue 2. Enqueue right (3) then left (1).
Queue: [3, 1]
Result so far: 2
Right child is enqueued before left child. This ensures the left child is processed last at each level.
Step 3: Dequeue 3. Enqueue right (4) then left (5).
Queue: [1, 4, 5]
Result so far: 3
Node 3 is dequeued. Its children are enqueued right-to-left: 4 first, then 5.
Step 4: Dequeue 1 (no children), then 4 (no children).
Queue: [5]
Result so far: 4
Node 1 is a leaf. Node 4 is a leaf. Only node 5 remains in the queue.
Step 5: Dequeue 5. Queue is empty. Done!
Queue: []
Result so far: 5
Node 5 is the last node dequeued. Because we enqueue right before left, the final node is always the bottom-left value.
Notice the pattern: by flipping the enqueue order, BFS naturally finishes at the bottom-left corner. The result variable gets overwritten with every node, and the final overwrite is the answer.
The code
from collections import deque
def find_bottom_left_value(root):
queue = deque([root])
result = root.val
while queue:
node = queue.popleft()
result = node.val
if node.right:
queue.append(node.right)
if node.left:
queue.append(node.left)
return result
Here is what each part does:
queue = deque([root])seeds the queue with the root. The problem guarantees at least one node, so no null check is needed.result = node.valoverwrites the result with every node dequeued. The last overwrite wins.if node.rightbeforeif node.leftis the key move. Right children enter the queue first, so left children at any given level are processed later.return resultgives back the last node dequeued, which is the leftmost node at the deepest level.
Complexity analysis
| Approach | Time | Space |
|---|---|---|
| BFS right-to-left | O(n) | O(n) |
Time - O(n): every node is enqueued and dequeued exactly once. The while loop runs n times total.
Space - O(n): the queue can hold up to n/2 nodes in the worst case (the widest level of a complete binary tree). For a skewed tree, the queue holds at most one node at a time, but the worst case is still O(n).
Building blocks
This problem is built on two reusable patterns:
1. BFS traversal with a queue. The standard template pushes the root, then loops while the queue is non-empty, dequeuing one node and enqueuing its children:
from collections import deque
def bfs(root):
queue = deque([root])
while queue:
node = queue.popleft()
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
2. Right-to-left BFS ordering. By swapping the enqueue order (right before left), you change which node BFS visits last. Instead of finishing at the bottom-right, it finishes at the bottom-left. This same trick applies any time you need the "last" element from a reversed perspective.
Edge cases
- Single node (no children): the root is both the deepest and the leftmost node. The queue drains after one iteration, and
resultequalsroot.val. - Left-skewed tree (every node has only a left child): each level has one node, and it is always a left child. BFS processes them top to bottom. The last node processed is the deepest (and only) node at the bottom level.
- Right-skewed tree (every node has only a right child): same as above but mirrored. Each level has one node. That single node is the leftmost (and only) node at its level, so the answer is the deepest node in the chain.
- Complete binary tree: the bottom level has the most nodes. With right-to-left BFS, the leftmost node at the bottom level is the last one dequeued because all right-side nodes at that level enter the queue first.
Do not confuse "bottom-left" with "the leftmost leaf." A leftmost leaf might not be at the deepest level. The problem asks for the leftmost node in the last (deepest) row, not the first leaf you encounter during traversal.
From understanding to recall
You just traced through a BFS solution that finds the bottom-left value by flipping the enqueue order. It is a clean trick, and it makes sense right now. But in an interview next month, will you remember to enqueue right before left? Or will you default to the standard order and then scramble to add level-tracking logic?
Understanding a pattern and being able to reproduce it under pressure are different skills. Spaced repetition bridges that gap. You practice the right-to-left BFS trick from memory at increasing intervals - first after a day, then three days, then a week. Each repetition reinforces the enqueue reversal and the "last node wins" insight until the pattern is automatic.
BFS right-to-left is one variation of roughly 60 reusable building blocks that cover hundreds of LeetCode problems. Drilling them individually with spaced repetition is far more effective than grinding random problems and hoping the patterns stick.
Related posts
- Binary Tree Level Order Traversal - The foundational BFS level-by-level template that this problem builds on
- Binary Tree Right Side View - Another BFS variation that extracts the last node at each level instead of the first
- Minimum Depth of Binary Tree - BFS used to find the shallowest leaf, showing how level-order traversal handles depth queries