Bird
Raised Fist0
DSA Pythonprogramming

DP on Trees Diameter of Tree in DSA Python

Choose your learning style10 modes available
Mental Model
The diameter of a tree is the longest path between any two nodes. We find it by exploring the longest paths from each node using dynamic programming.
Analogy: Imagine a network of roads connecting towns. The diameter is the longest route you can travel without repeating towns. We find it by checking the longest roads from each town and combining them.
    1
   / \
  2   3
     / \
    4   5

Nodes connected like a tree with branches.
Dry Run Walkthrough
Input: Tree edges: 1-2, 1-3, 3-4, 3-5
Goal: Find the longest path between any two nodes in the tree (diameter).
Step 1: Start DFS from node 1, calculate longest path down each subtree
At node 1: explore children 2 and 3
Why: We need to find longest paths from node 1 to its descendants
Step 2: At node 2 (leaf), longest path down is 0
Node 2: longest_down = 0
Why: Leaf nodes have no children, so longest path down is zero
Step 3: At node 3, explore children 4 and 5
At node 3: children 4 and 5 to process
Why: We need longest paths from node 3 to its descendants
Step 4: At node 4 (leaf), longest path down is 0
Node 4: longest_down = 0
Why: Leaf node
Step 5: At node 5 (leaf), longest path down is 0
Node 5: longest_down = 0
Why: Leaf node
Step 6: At node 3, longest_down = max(0,0) + 1 = 1; diameter through 3 = 0 + 0 + 2 = 2
Node 3: longest_down=1, diameter_candidate=2
Why: Longest path down is one edge plus max child's longest_down; diameter through node is sum of top two longest_down + 2 edges
Step 7: At node 1, longest_down = max(0,1) + 1 = 2; diameter through 1 = 0 + 1 + 2 = 3
Node 1: longest_down=2, diameter_candidate=3
Why: Combine longest paths from children to find diameter passing through node 1
Result:
Diameter is 3 edges: path 2 -> 1 -> 3 -> 4 (or 5)
1 -> 2 -> null
1 -> [longest_down=2] -> 3 -> [longest_down=1] -> 4 -> null
Annotated Code
DSA Python
class TreeNode:
    def __init__(self, val):
        self.val = val
        self.children = []

class TreeDiameter:
    def __init__(self):
        self.diameter = 0

    def dfs(self, node):
        if not node:
            return 0
        max1 = 0  # longest path down
        max2 = 0  # second longest path down
        for child in node.children:
            length = self.dfs(child) + 1
            if length > max1:
                max2 = max1
                max1 = length
            elif length > max2:
                max2 = length
        self.diameter = max(self.diameter, max1 + max2)
        return max1

# Build tree from example
root = TreeNode(1)
node2 = TreeNode(2)
node3 = TreeNode(3)
node4 = TreeNode(4)
node5 = TreeNode(5)
root.children = [node2, node3]
node3.children = [node4, node5]

solver = TreeDiameter()
solver.dfs(root)
print(solver.diameter)
for child in node.children:
Traverse all children to find longest paths down
length = self.dfs(child) + 1
Calculate path length from current node through child
if length > max1:
Update longest and second longest paths
self.diameter = max(self.diameter, max1 + max2)
Update diameter with sum of two longest paths through this node
return max1
Return longest path down for parent's calculation
OutputSuccess
3
Complexity Analysis
Time: O(n) because we visit each node once during DFS
Space: O(n) due to recursion stack in worst case (skewed tree)
vs Alternative: Naive approach checking all pairs is O(n^2), DP on trees is efficient O(n)
Edge Cases
Single node tree
Diameter is 0 because no edges exist
DSA Python
if not node:
    return 0
Linear tree (chain)
Diameter equals number of edges in chain
DSA Python
self.diameter = max(self.diameter, max1 + max2)
Tree with multiple branches
Diameter correctly computed as longest path crossing any node
DSA Python
for child in node.children:
When to Use This Pattern
When asked for longest path between any two nodes in a tree, use DP on trees to find longest downward paths and combine them to get diameter.
Common Mistakes
Mistake: Only tracking one longest path from children, missing second longest for diameter calculation
Fix: Track two longest paths from children to compute diameter passing through node
Mistake: Returning sum of longest paths instead of max sum for diameter
Fix: Update diameter with max of current diameter and sum of two longest child paths
Summary
Finds the longest path between any two nodes in a tree using DFS and dynamic programming.
Use when you need the maximum distance between nodes in a tree structure.
The diameter is the sum of the two longest downward paths from a node, combined at that node.

Practice

(1/5)
1. What is the diameter of a tree in terms of its nodes?
easy
A. The total number of nodes in the tree
B. The number of leaf nodes in the tree
C. The longest path between any two nodes in the tree
D. The height of the tree from the root node

Solution

  1. Step 1: Understand the definition of tree diameter

    The diameter is the longest path between any two nodes, not just from the root or leaf count.
  2. Step 2: Compare options with definition

    Only The longest path between any two nodes in the tree correctly describes the longest path between any two nodes.
  3. Final Answer:

    The longest path between any two nodes in the tree -> Option C
  4. Quick Check:

    Diameter = longest path [OK]
Hint: Diameter = longest path between any two nodes [OK]
Common Mistakes:
  • Confusing diameter with tree height
  • Thinking diameter is number of leaves
  • Assuming diameter is total nodes count
2. Which of the following is the correct Python syntax to declare a recursive function to find the diameter of a tree?
easy
A. def diameter(node):
B. function diameter(node) {
C. def diameter[node]:
D. diameter = lambda node:

Solution

  1. Step 1: Identify correct Python function syntax

    Python functions use 'def' keyword followed by function name and parentheses with parameters.
  2. Step 2: Check each option

    def diameter(node): uses correct Python syntax. function diameter(node) { is JavaScript style. def diameter[node]: uses wrong brackets. diameter = lambda node: is incomplete lambda syntax.
  3. Final Answer:

    def diameter(node): -> Option A
  4. Quick Check:

    Python function syntax = def name(params): [OK]
Hint: Python functions start with def and parentheses [OK]
Common Mistakes:
  • Using curly braces instead of colon
  • Using square brackets for parameters
  • Incorrect lambda syntax for recursion
3. Given the following tree edges and code snippet, what is the diameter of the tree?
edges = [(1,2), (2,3), (2,4), (4,5)]

# Code snippet
from collections import defaultdict

tree = defaultdict(list)
for u,v in edges:
    tree[u].append(v)
    tree[v].append(u)

max_diameter = 0
def dfs(node, parent):
    global max_diameter
    max1 = max2 = 0
    for child in tree[node]:
        if child == parent:
            continue
        depth = dfs(child, node)
        if depth > max1:
            max2 = max1
            max1 = depth
        elif depth > max2:
            max2 = depth
    max_diameter = max(max_diameter, max1 + max2)
    return max1 + 1

dfs(1, -1)
print(max_diameter)
medium
A. 3
B. 4
C. 5
D. 2

Solution

  1. Step 1: Build the tree and understand structure

    The tree edges form: 1-2-3, 2-4-5. The longest path is from node 3 to node 5 via 2 and 4.
  2. Step 2: Calculate longest path length

    Path 3->2->4->5 has 3 edges, so diameter is 3 edges = 4 nodes in path length. The code counts edges, so max_diameter = 3 edges.
  3. Final Answer:

    3 -> Option A
  4. Quick Check:

    Longest path edges = 3 [OK]
Hint: Diameter = max sum of two largest depths at any node [OK]
Common Mistakes:
  • Counting nodes instead of edges for diameter
  • Ignoring parent check in DFS
  • Mixing up max1 and max2 updates
4. The following code attempts to find the diameter of a tree but produces incorrect output. What is the bug?
def dfs(node, parent):
    max_depth = 0
    for child in tree[node]:
        if child != parent:
            depth = dfs(child, node)
            if depth > max_depth:
                max_depth = depth
    return max_depth + 1

max_diameter = 0
def find_diameter(node, parent):
    global max_diameter
    depths = []
    for child in tree[node]:
        if child != parent:
            depths.append(dfs(child, node))
    if len(depths) >= 2:
        depths.sort(reverse=True)
        max_diameter = max(max_diameter, depths[0] + depths[1])
    for child in tree[node]:
        if child != parent:
            find_diameter(child, node)

find_diameter(1, -1)
print(max_diameter)
medium
A. The recursive call to find_diameter is missing
B. max_diameter is not updated globally
C. Sorting depths in descending order is incorrect
D. Only updates max_diameter when len(depths) >= 2, missing updates for nodes with fewer than 2 children

Solution

  1. Step 1: Identify the conditional update bug

    The code only updates max_diameter if len(depths) >= 2, but to mimic standard algorithm, it should always update using the two largest depths (with second as 0 if fewer children).
  2. Step 2: Understand impact on chain trees

    In chain trees, nodes often have at most 1 child (excluding parent), so the condition skips updates, leaving max_diameter = 0 incorrectly.
  3. Final Answer:

    Only updates max_diameter when len(depths) >= 2, missing updates for nodes with fewer than 2 children -> Option D
  4. Quick Check:

    Pad missing depths with 0 for diameter update [OK]
Hint: Always update diameter with top two downward depths (pad 0 if needed) [OK]
Common Mistakes:
  • Not updating global max_diameter
  • Incorrect sorting order of depths
  • Missing recursive calls in diameter function
5. You want to find the diameter of a weighted tree where edges have different lengths. Which modification to the standard DP on trees diameter algorithm is correct? A weighted tree is represented as adjacency list with tuples (neighbor, weight).
tree = {
  1: [(2, 3), (3, 2)],
  2: [(1, 3), (4, 4)],
  3: [(1, 2)],
  4: [(2, 4)]
}

# Which code snippet correctly computes diameter?
hard
A. Use BFS twice ignoring weights to find diameter
B. Use dfs to return max weighted depth, update diameter by sum of top two weighted depths
C. Ignore weights and count edges only for diameter
D. Sum all weights in the tree and divide by 2

Solution

  1. Step 1: Understand weighted tree diameter

    Diameter is longest weighted path, so weights must be included in depth calculations.
  2. Step 2: Modify DFS to return max weighted depth and update diameter

    DFS returns max weighted depth from node; diameter updated by sum of two largest weighted depths.
  3. Final Answer:

    Use dfs to return max weighted depth, update diameter by sum of top two weighted depths -> Option B
  4. Quick Check:

    Weighted diameter = sum of max weighted depths [OK]
Hint: Include edge weights in depth sums for weighted diameter [OK]
Common Mistakes:
  • Ignoring weights and treating as unweighted
  • Using BFS without weights for weighted diameter
  • Summing all weights instead of longest path
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard