Given the root of a binary tree, return its depth.
The depth 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.
Example 1:
Input: root = [1,2,3,null,null,4]
Output: 3Example 2:
Input: root = []
Output: 0Constraints:
0 <= The number of nodes in the tree <= 100.-100 <= Node.val <= 100
You should aim for a solution with O(n) time and O(n) space, where n is the number of nodes in the tree.
From the definition of binary tree's maximum depth, Can you think of a way to achieve this recursively? Maybe you should consider the max depth of the subtrees first before computing the maxdepth at the root.
We use the Depth First Search (DFS) algorithm to find the maximum depth of a binary tree, starting from the root. For the subtrees rooted at the left and right children of the root node, we calculate their maximum depths recursively going through left and right subtrees. We return 1 + max(leftDepth, rightDepth). Why?
The +1 accounts for the current node, as it contributes to the current depth in the recursion call. We pass the maximum depth from the current node's left and right subtrees to its parent because the current maximum depth determines the longest path from the parent to a leaf node through this subtree.
Before attempting this problem, you should be comfortable with:
Recursive DFS computes the maximum depth of a binary tree by exploring every node.
The idea is simple:
None, its depth is 0.So for each node:
1 for the current node.root is null, return 0.leftDepth = maxDepth(root.left).rightDepth = maxDepth(root.right).1 + max(leftDepth, rightDepth).# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def maxDepth(self, root: Optional[TreeNode]) -> int:
if not root:
return 0
return 1 + max(self.maxDepth(root.left), self.maxDepth(root.right))Where is the number of nodes in the tree and is the height of the tree.
Instead of relying on recursion to explore the tree, we can simulate DFS explicitly using a stack.
The stack will store pairs of:
Every time we pop a node from the stack:
This approach works like a manual DFS where we keep track of depth ourselves.
It avoids recursion and is useful when recursion depth may become too large.
root is null, return 0.(root, 1) to represent depth 1.maxDepth = 0.(node, depth).maxDepth = max(maxDepth, depth).(node.left, depth + 1) onto the stack if left child exists.(node.right, depth + 1) onto the stack if right child exists.maxDepth.# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def maxDepth(self, root: Optional[TreeNode]) -> int:
stack = [[root, 1]]
res = 0
while stack:
node, depth = stack.pop()
if node:
res = max(res, depth)
stack.append([node.left, depth + 1])
stack.append([node.right, depth + 1])
return resBreadth-First Search (BFS) processes the tree level by level.
This makes it a perfect fit for computing the maximum depth because:
We simply count how many levels we traverse until the queue becomes empty.
Think of the queue like a moving frontier:
The number of BFS layers processed is exactly the depth of the tree.
root == null), return 0.root.level = 0.size = len(queue)).size nodes:level.level when the queue becomes empty.# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def maxDepth(self, root: Optional[TreeNode]) -> int:
q = deque()
if root:
q.append(root)
level = 0
while q:
for i in range(len(q)):
node = q.popleft()
if node.left:
q.append(node.left)
if node.right:
q.append(node.right)
level += 1
return levelDepth is measured from the root down (root has depth 1 or 0 depending on convention), while height is measured from the leaves up. The maximum depth of a tree equals its height when counting from root. Be consistent with whether you start counting at 0 or 1.
# If root is None, depth is 0 (no nodes)
# If root exists with no children, depth is 1 (one node)
def maxDepth(self, root):
if not root:
return 0 # Base case: empty tree has depth 0
return 1 + max(self.maxDepth(root.left), self.maxDepth(root.right))An empty tree (null root) has a depth of 0. Failing to check for this base case before accessing node properties will cause a null pointer exception.
# Wrong: No null check
def maxDepth(self, root):
return 1 + max(self.maxDepth(root.left), self.maxDepth(root.right))
# Crashes when root is None
# Correct: Handle empty tree first
def maxDepth(self, root):
if not root:
return 0
return 1 + max(self.maxDepth(root.left), self.maxDepth(root.right))
Sign in to join the discussion