Maximum Depth of Binary Tree
Given the root of a binary tree, return its maximum depth — the number of nodes along the longest path from the root down to the farthest leaf. The tree is given as a level-order array where null marks a missing child. Use depth-first search from the root: the depth of a node is 1 plus the larger of its two subtree depths , and an empty subtree has depth 0.
Constraints
- The number of nodes in the tree is in the range [0, 104]
- -100 ≤ Node.val ≤ 100
Example
root = [3,9,20,null,null,15,7]3Explanation The longest path is 3 → 20 → 15 (or 3 → 20 → 7), which visits 3 nodes.
In plain terms
- Level order
- Listing tree node values top-to-bottom, left-to-right, the way LeetCode serializes trees, with null standing in for a missing child.
- Leaf
- A node with no children — the very end of a branch.
Recurse to the leaves, then combine depths on the way back up
Node 9 is a leaf — depth 1.
What happens in this step
dfs(index 1) → node 9 node.left = null → dfs(null) = 0 node.right = null → dfs(null) = 0 depth(9) = 1 + max(0, 0) = 1 Node 9 has no children, so both recursive calls hit the null base case and return 0 — its own depth is just 1.
Steps to visualize
- Recurse into the left and right subtree of every node.
- An empty subtree (a null child) has depth 0 and returns immediately.
- A leaf returns 1, since it has no deeper subtree to add to.
- Every other node's depth is 1 plus the larger of its two children's depths.
- The recursion unwinds back to the root, which reports the depth of the whole tree.
Walk through the code
Same walkthrough, now with the code. Press Next to move one step and watch which lines run.
Node 9 is a leaf — depth 1.
What happens in this step
dfs(index 1) → node 9 node.left = null → dfs(null) = 0 node.right = null → dfs(null) = 0 depth(9) = 1 + max(0, 0) = 1 Node 9 has no children, so both recursive calls hit the null base case and return 0 — its own depth is just 1.
Solution
function maxDepth(values) {
function buildTree(arr) {
if (!arr || arr.length === 0 || arr[0] === null) return null;
const root = { val: arr[0], left: null, right: null };
const queue = [root];
let i = 1;
while (queue.length > 0 && i < arr.length) {
const node = queue.shift();
if (i < arr.length) {
const leftVal = arr[i++];
if (leftVal !== null && leftVal !== undefined) {
node.left = { val: leftVal, left: null, right: null };
queue.push(node.left);
}
}
if (i < arr.length) {
const rightVal = arr[i++];
if (rightVal !== null && rightVal !== undefined) {
node.right = { val: rightVal, left: null, right: null };
queue.push(node.right);
}
}
}
return root;
}
function dfs(node) {
if (!node) return 0;
return 1 + Math.max(dfs(node.left), dfs(node.right));
}
return dfs(buildTree(values));
}- Time
- O(n)
- Space
- O(h) — h is the height of the tree, for the recursion stack
Test cases
| Input | Expected | Covers |
|---|---|---|
root = [3,9,20,null,null,15,7] | 3 | example from the docstring |
root = [] | 0 | empty tree has depth 0 |
root = [1] | 1 | smallest valid non-empty tree, a single node |
root = [1,2,null,3] | 3 | a chain of only left children |
root = [1,null,2,null,3] | 3 | a chain of only right children |
root = [1,2,3] | 2 | a small balanced tree, both children are leaves |
root = [1,2,3,4,5,6,7] | 3 | a complete tree with two full levels beneath the root |
root = [null] | 0 | an explicit null root is treated the same as an empty tree |