Find Bottom Left Tree Value
MediumUpdated: Aug 2, 2025
Practice on:
Problem
Given the root of a binary tree, return the leftmost value in the last row of the tree.
Examples
Example 1:
graph TD A(2) A(2) --- B(1):::leftMost A(2) --- C(3) classDef leftMost fill:#3CB371,stroke:#000,stroke-width:1px,color:#fff;
Input: root = [2,1,3]
Output: 1
Example 2:
graph TD A(1) A(1) --- B(2) A(1) --- C(3) B(2) --- D(4):::leftMost B ~~~ N1:::hidden C(3) --- E(5) C(3) --- F(6) E(5) --- G(7):::leftMost E ~~~ N2:::hidden classDef leftMost fill:#3CB371,stroke:#000,stroke-width:1px,color:#fff; classDef hidden display:none
Input: root = [1,2,3,4,null,5,6,null,null,7]
Output: 7
Solution
Understanding the problem. WE can't just go left and elft and find the answer. We can also have the answer in right part of the root. So, idea is to get the leftmost value in the last row. That implies doing level order traversal.
Method 1 - Level Order Traversal - Left to Right
We will use Breadth-First Search (BFS) using a queue to traverse the tree level by level and ensure we capture the leftmost value at the last row. Here's the approach:
- Initialisation: Start the BFS traversal with the root node in the queue.
- Update Row: At each level, iterate through all nodes in the current level of the queue. Keep track of the leftmost node at that level.
- Leftmost Tracking: For each level, ensure the value stored corresponds to the first node in the level.
- Continue Traversal: Add the left and right children of each node into the queue to enable processing of the next level.
- Result: The last updated leftmost value is the answer.
Code
Java
class Solution {
public int findBottomLeftValue(TreeNode root) {
int ans = 0; // Result variable for the leftmost value
Queue<TreeNode> queue = new LinkedList<>(); // BFS queue
queue.add(root); // Start BFS from root
while (!queue.isEmpty()) {
int size = queue.size(); // Number of nodes at the current level
ans = queue.peek().val; // Leftmost value in the current level
for (int i = 0; i < size; i++) {
TreeNode curr = queue.poll(); // Remove current node from the queue
// Add children to the queue for the next level
if (curr.left != null) queue.add(curr.left);
if (curr.right != null) queue.add(curr.right);
}
}
return ans; // The leftmost value at the last row
}
}
Python
class Solution:
def findBottomLeftValue(self, root: Optional[TreeNode]) -> int:
ans: int = 0 # Result variable
queue: deque[TreeNode] = deque([root]) # BFS queue starting with root
while queue:
size: int = len(queue) # Number of nodes at current level
ans = queue[0].val # Leftmost value in the current level
for _ in range(size):
curr: Optional[TreeNode] = queue.popleft() # Remove current node from the queue
# Add children to the queue for next level
if curr.left:
queue.append(curr.left)
if curr.right:
queue.append(curr.right)
return ans # The leftmost value at the last row
Complexity
- ⏰ Time complexity:
O(n), wherenis the number of nodes in the binary tree, as this algorithm visits each node exactly once. - 🧺 Space complexity:
O(n).- The queue stores nodes at most one full level of the tree at a time.
- In the worst case (balanced binary tree), the last row may have
n/2nodes.
Method 2 - BFS - Right to Left
By traversing nodes right to left, we ensure that the last node processed at the deepest level during BFS is the leftmost node. Therefore, there’s no need to track the first element added; the last value in the traversal is the result.
Code
Java
class Solution {
public int findBottomLeftValue(TreeNode root) {
Queue<TreeNode> queue = new LinkedList<>();
queue.add(root);
while (!queue.isEmpty()) {
root = queue.poll();
if (root.right != null)
queue.add(root.right);
if (root.left != null)
queue.add(root.left);
}
return root.val;
}
}
Python
class TreeNode:
def __init__(self, val: int = 0, left: Optional['TreeNode'] = None, right: Optional['TreeNode'] = None):
self.val = val
self.left = left
self.right = right
class Solution:
def findBottomLeftValue(self, root: Optional[TreeNode]) -> int:
queue = deque([root])
while queue:
root = queue.popleft()
# Add right child first, then left child for right-to-left traversal
if root.right:
queue.append(root.right)
if root.left:
queue.append(root.left)
return root.val
Complexity
- ⏰ Time complexity:
O(n) - 🧺 Space complexity:
O(n)
Method 3 - DFS
Code
Java
class Solution {
public int findBottomLeftValue(TreeNode root) {
return findBottomLeftValue(root, 1, new int[]{0,0});
}
public int findBottomLeftValue(TreeNode root, int depth, int[] res) {
if (res[1]<depth) {
res[0]=root.val;
res[1]=depth;
}
if (root.left!=null) {
findBottomLeftValue(root.left, depth+1, res);
}
if (root.right!=null) {
findBottomLeftValue(root.right, depth+1, res);
}
return res[0];
}
}
Python
class Solution:
def findBottomLeftValue(self, root: Optional[TreeNode]) -> int:
res = [0, 0] # res[0] = value of leftmost node, res[1] = max depth
return self._findBottomLeftValue(root, 1, res)
def _findBottomLeftValue(self, root: Optional[TreeNode], depth: int, res: list[int]) -> int:
if res[1] < depth:
res[0] = root.val
res[1] = depth
if root.left:
self._findBottomLeftValue(root.left, depth + 1, res)
if root.right:
self._findBottomLeftValue(root.right, depth + 1, res)
return res[0]
Complexity
- ⏰ Time complexity:
O(n) - 🧺 Space complexity:
O(h)