Find Bottom Left Tree Value
MedPrompt
Given the root of a binary tree, return the leftmost value in the last row of the tree.
Example 1:
Input: root = [2,1,3]
Output: 1Example 2:
Input: root = [1,2,3,4,null,5,6,null,null,7]
Output: 7
Constraints:
- The number of nodes in the tree is in the range
[1, 104]. -231 <= Node.val <= 231 - 1
Approaches
2 approaches with complexity analysis and trade-offs.
This approach utilizes a recursive Depth-First Search (DFS) to traverse the tree. By keeping track of the traversal depth, we can identify the leftmost node at the deepest level encountered so far. The key is to traverse the left subtree before the right subtree.
Algorithm
- Initialize
maxLevel = -1andbottomLeftValuewith a default value. - Create a recursive helper function
dfs(node, level). - Start the traversal by calling
dfs(root, 0). - In
dfs(node, level):- If
nodeis null, return. - If the current
levelis greater thanmaxLevel, updatemaxLevel = levelandbottomLeftValue = node.val. - Recursively call
dfs(node.left, level + 1). - Recursively call
dfs(node.right, level + 1).
- If
- After the initial call completes, return
bottomLeftValue.
Walkthrough
The core idea is to traverse the tree while passing down the current level (or depth). We maintain two global or member variables: maxLevel to store the maximum depth reached, and bottomLeftValue to store the value of the leftmost node at that depth.\n\nWe define a helper function, dfs(node, level). The traversal order is crucial: we must visit the left subtree before the right one. This ensures that when we first encounter a new, deeper level, the node we are at is guaranteed to be the leftmost one for that level.\n\nInside the recursive function, we first check if the current level is greater than maxLevel. If it is, we've found a new deepest level. We update maxLevel to the current level and set bottomLeftValue to the current node's value. Then, we proceed with the recursive calls for the left and right children.\n\n```java
/**
-
Definition for a binary tree node.
-
public class TreeNode {
-
int val; -
TreeNode left; -
TreeNode right; -
TreeNode() {} -
TreeNode(int val) { this.val = val; } -
TreeNode(int val, TreeNode left, TreeNode right) { -
this.val = val; -
this.left = left; -
this.right = right; -
} -
} */ class Solution { private int maxLevel = -1; private int bottomLeftValue = 0;
public int findBottomLeftValue(TreeNode root) { dfs(root, 0); return bottomLeftValue; }
private void dfs(TreeNode node, int level) { if (node == null) { return; }
// If this is the first time we visit this level, it must be the leftmost node.if (level > maxLevel) { maxLevel = level; bottomLeftValue = node.val;} // Traverse left first to ensure we see the leftmost node first at any level.dfs(node.left, level + 1);dfs(node.right, level + 1);} }
Complexity
Time
O(N), where N is the number of nodes in the tree. We visit each node exactly once.
Space
O(H), where H is the height of the tree. This space is used by the recursion stack. In the worst case of a skewed tree, H can be equal to N, leading to O(N) space. For a balanced tree, it's O(log N).
Trade-offs
Pros
Can be more space-efficient than BFS for wide, shallow trees (e.g., complete binary trees where H = log N).
The recursive implementation is often concise and elegant.
Cons
May cause a stack overflow for extremely deep trees due to deep recursion.
In the worst-case (a skewed tree), the space complexity becomes O(N), which is no better than BFS.
Solutions
Solution
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode() {} * TreeNode(int val) { this.val = val; } * TreeNode(int val, TreeNode left, TreeNode right) { * this.val = val; * this.left = left; * this.right = right; * } * } */ class Solution { public int findBottomLeftValue ( TreeNode root ) { Queue < TreeNode > q = new ArrayDeque <>(); q . offer ( root ); int ans = 0 ; while (! q . isEmpty ()) { ans = q . peek (). val ; for ( int i = q . size (); i > 0 ; -- i ) { TreeNode node = q . poll (); if ( node . left != null ) { q . offer ( node . left ); } if ( node . right != null ) { q . offer ( node . right ); } } } return ans ; } }Video walkthrough
Newsletter
One sharp idea, every week
System design and interview prep — short enough to finish.
No spam. Unsubscribe anytime.
Practice
Same difficulty — related problems to reinforce the pattern.