Before attempting this problem, you should be comfortable with:
The height of a node is defined as the length of the longest downward path to a leaf node from that node.
The diameter of a tree is the longest path between any two nodes. This path must pass through some node as the highest point (closest to root). At that node, the path goes down through two different children. So the longest path through any node equals the sum of the two largest heights among its children. By computing heights recursively and tracking the maximum path length, we find the diameter.
0.1 as the current node's height.class Solution:
def diameter(self, root: 'Node') -> int:
diameter = 0
def height(node):
""" return the height of the node """
nonlocal diameter
if len(node.children) == 0:
return 0
# select the top two heights
max_height_1, max_height_2 = 0, 0
for child in node.children:
parent_height = height(child) + 1
if parent_height > max_height_1:
max_height_1, max_height_2 = parent_height, max_height_1
elif parent_height > max_height_2:
max_height_2 = parent_height
# calculate the distance between the two farthest leaves nodes.
distance = max_height_1 + max_height_2
diameter = max(diameter, distance)
return max_height_1
height(root)
return diameterWhere is the number of nodes in the tree.
The depth of a node is the length of the path to the root node.
Instead of tracking heights (distance down to leaves), we can track depths (distance from root). The diameter through a node equals the sum of the two deepest leaf paths minus twice the current node's depth. This accounts for the path going down to one leaf, back up to the current node, and down to another leaf.
max_depth_1 + max_depth_2 - 2 * current_depth.class Solution:
def diameter(self, root: 'Node') -> int:
diameter = 0
def maxDepth(node, curr_depth):
""" return the maximum depth of leaves nodes
descending from the current node
"""
nonlocal diameter
if len(node.children) == 0:
return curr_depth
# select the top 2 depths from its children
max_depth_1, max_depth_2 = curr_depth, 0
for child in node.children:
depth = maxDepth(child, curr_depth+1)
if depth > max_depth_1:
max_depth_1, max_depth_2 = depth, max_depth_1
elif depth > max_depth_2:
max_depth_2 = depth
# calculate the distance between the two farthest leaves nodes
distance = max_depth_1 + max_depth_2 - 2 * curr_depth
diameter = max(diameter, distance)
return max_depth_1
maxDepth(root, 0)
return diameterWhere is the number of nodes in the tree.
A common mistake is assuming the diameter must pass through the root node. The longest path may be entirely within a subtree. You must track the maximum diameter found at any node, not just the root.
# Wrong: Only checking diameter at root level
def diameter(root):
heights = [height(child) for child in root.children]
heights.sort(reverse=True)
return heights[0] + heights[1] if len(heights) >= 2 else 0
# Correct: Track max diameter across all nodes
def diameter(root):
max_diameter = 0
def height(node):
nonlocal max_diameter
# ... update max_diameter at every node
height(root)
return max_diameterHeight (distance down to leaves) and depth (distance from root) are different concepts. Mixing them up leads to incorrect diameter calculations. Height returns the longest path downward from a node, while depth is passed as a parameter representing distance from root.
# Using height: returns longest path DOWN from node
def height(node):
if not node.children:
return 0
return 1 + max(height(child) for child in node.children)
# Using depth: distance FROM ROOT passed as parameter
def maxDepth(node, curr_depth):
if not node.children:
return curr_depth # Returns absolute depth
return max(maxDepth(child, curr_depth + 1) for child in node.children)To compute the diameter through a node, you need the two largest heights among its children. Tracking only the maximum height misses the second-largest, which is needed for the path length calculation.
# Wrong: Only tracking one maximum
max_height = 0
for child in node.children:
max_height = max(max_height, height(child) + 1)
diameter = max_height # Missing the second branch!
# Correct: Track top two heights
max_height_1, max_height_2 = 0, 0
for child in node.children:
h = height(child) + 1
if h > max_height_1:
max_height_1, max_height_2 = h, max_height_1
elif h > max_height_2:
max_height_2 = h
diameter = max_height_1 + max_height_2