L14. Maximum Depth in Binary Tree | Height of Binary Tree
Calculating the maximum depth (or height) of a binary tree is a foundational problem in data structures and algorithms. This module explores how to compute this depth efficiently using both recursive and level-order traversal strategies, complete with complexity analyses and production-ready implementations in C++ and Java.
1. Problem Statement & Definition of Maximum Depth
The maximum depth (often referred to as the height) of a binary tree is defined as the number of nodes along the longest path from the root node down to the farthest leaf node.
- A tree with a single root node has a depth of
1. - An empty tree (where the root is
null) has a depth of0.
Root (1)
/ \
(2) (3)
/ \
(4) (6)
/
(5)
In the example tree above, the longest path goes 1 -> 3 -> 4 -> 5, giving a maximum depth/height of 4.
2. Core Mental Model: The Recursive Subproblem
When standing at any arbitrary node in a binary tree, we do not need to manually trace every single path across the entire structure at once. Instead, we can break the problem down into a self-similar subproblem:
Core Insight: The maximum depth starting from any node is equal to
1(accounting for the current node itself) plus the maximum of the depths of its left subtree and right subtree.
Mathematical Recurrence Relation
- Base Case: If the node is
null(it does not exist), its depth is0.
3. Step-by-Step Tree Dry Run Walkthrough
Let us trace how the recursive approach computes the height for our example tree:
1
/ \
2 3
/ \
4 6
/
5
- Start at Root (
1): We need1 + max(leftHeight, rightHeight). We explore the left child (2) first. - At Node
2:- Left child is
null(height0). - Right child is
null(height0). - Height of node
2= . Returns1to Root1.
- Left child is
- Back to Root (
1): Left subtree height is1. Now we explore the right child (3). - At Node
3: We need . We explore node3's left child (4). - At Node
4: We explore its left child (5). - At Node
5:- Left child is
null(0), Right child isnull(0). - Height of node
5= . Returns1to Node4.
- Left child is
- Back to Node
4: Left child returned1, right child (null) is0.- Height of node
4= . Returns2to Node3.
- Height of node
- At Node
6(Right child of3):- Left and right children are
null. - Height of node
6= . Returns1to Node3.
- Left and right children are
- Back to Node
3: Left child (4) returned2, right child (6) returned1.- Height of node
3= . Returns3to Root1.
- Height of node
- Final Calculation at Root (
1): Left subtree returned1, right subtree returned3.- Total Max Depth = .
4. Naive vs. Optimal Traversal Strategies
When solving tree depth problems, developers generally choose between two primary traversal paradigms:
5. Complete Implementation Code
C++ Implementation
#include <iostream>
#include <algorithm>
// Definition for a binary tree node.
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};
class Solution {
public:
int maxDepth(TreeNode* root) {
// Base case: if the node is null, depth is 0
if (root == nullptr) {
return 0;
}
// Recursively compute left and right subtree depths
int leftHeight = maxDepth(root->left);
int rightHeight = maxDepth(root->right);
// Current depth is 1 (for the root) + max of subtrees
return 1 + std::max(leftHeight, rightHeight);
}
};
Java Implementation
// Definition for a binary tree node.
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) {
val = x;
left = null;
right = null;
}
}
class Solution {
public int maxDepth(TreeNode root) {
// Base case: if the node is null, depth is 0
if (root == null) {
return 0;
}
// Recursively compute left and right subtree depths
int leftHeight = maxDepth(root.left);
int rightHeight = maxDepth(root.right);
// Current depth is 1 (for the root) + max of subtrees
return 1 + Math.max(leftHeight, rightHeight);
}
}
6. Complexity Analysis
- Time Complexity: , where is the total number of nodes in the binary tree. Every single node must be visited at least once to account for its contribution to the height. This is asymptotically optimal because you cannot verify the depth without inspecting all nodes.
- Space Complexity:
- Balanced Tree: auxiliary stack space due to the recursive call stack height.
- Skewed Tree (Linear/Degenerate Tree): auxiliary stack space in the absolute worst case where every node has only one child (forming a straight line).
7. Summary and Key Takeaways
- Definition: The maximum depth of a binary tree is the length of the longest path from the root node to the deepest leaf node.
- Optimal Recurrence: encapsulates the entire logic cleanly.
- Base Case: Always handle the
nullnode condition by returning0to terminate recursive calls safely. - Traversal Options: Both recursive (DFS) and level-order (BFS) approaches can solve this, but recursion is favored when tree heights are balanced ( space).
- Time Complexity Bound: time is strictly required since every node must be visited.
- Worst-Case Space: Skewed linear trees consume call stack space, whereas balanced trees consume stack space.