Compute the Diameter of an Undirected Tree
Company: Qualcomm
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Technical Screen
Overview: Compute the diameter of a large undirected tree, measured by the number of edges on its longest simple path. The exercise tests adjacency construction, linear-time tree traversal, endpoint reasoning, recursion-depth awareness, and edge cases such as a single-node tree.
Constraints
- 1 <= n <= 100000
- len(edges) == n - 1
- 0 <= u, v < n and u != v for every edge [u, v]
- The input graph is connected and contains no cycle, so it is always a tree.
- Edges are undirected: [u, v] and [v, u] describe the same edge, and the pairs may be listed in any order.
- The maximum runs over every pair of nodes; a longest path need not pass through node 0 or through the highest-degree node.
- Every input value is a node index of at most n - 1 <= 99999 and the answer is at most n - 1 <= 99999, so no quantity approaches a 32-bit integer limit or a JavaScript precision limit; `int` is the correct width in Java and C++.
- `edges` must not be mutated.
Examples
Input: (5, [[0,1],[1,2],[1,3],[3,4]])
Expected Output: 3
Explanation: Source example 1, carried over verbatim. Node 1 joins 0, 2 and 3, and node 3 also holds 4. The longest simple paths are 2-1-3-4 and 0-1-3-4, both 3 edges, so the diameter is 3.
Input: (1, [])
Expected Output: 0
Explanation: Source example 2, carried over verbatim. A single node has no edges, so the longest simple path has 0 edges.
Hints
- The diameter belongs to the whole tree, not to any one node. How far the deepest node sits from node `0` answers a different question -- try that idea on a tree where node `0` is a leaf dangling off the middle of a long chain.
- If you root the tree and compute each node's height, remember that the longest path bends at some node. That node is rarely the root, so whatever quantity you form at a node has to be maximised over **all** nodes before you report it.
- A different route: suppose you already knew one endpoint of some longest path. Finding the other endpoint is then a single traversal. So the question becomes how to get hold of one genuine endpoint cheaply -- and one traversal from an arbitrary start is enough to land on one.
- Whatever traversal you choose, keep it iterative with an explicit queue or stack. `n` reaches 100000 and a tree that shape can be a single chain, deep enough to exhaust the recursion limit in Python and the call stack in Java. Also remember to add every edge to the adjacency structure in **both** directions.