Max Height Calculation — Problem Statement & Solution Guide

RecursionMediumMixed
TimeO(N)
|
SpaceO(H)

Quick Answer & Algorithm Key Takeaway

Master coding challenges related to Recursion and solve the Max Height Calculation problem optimally.

TopicRecursion
PatternMixed
TimeO(N)
SpaceO(H)

Problem Description

Given a rooted tree with N distinct nodes, compute its maximum height measured as the number of nodes on the longest root‑to‑leaf path (both endpoints inclusive). The tree is supplied as follows: the first line contains the integer N. Each of the next N lines describes one node. A line starts with the node's identifier, followed by an integer C indicating how many direct children it has, then C identifiers of those children separated by spaces. All identifiers are unique and the structure forms a single rooted tree (exactly one node has no parent). Output a single integer – the tree's maximum height.

DSA Pattern Breakdown

DSA Pattern Breakdown

"Max Height Calculation"

medium

WHY DOES IT MATTER?

Computing tree height is a foundational pattern for any problem that requires understanding hierarchical depth, such as evaluating expression trees, file system depth, or organizational charts. Mastery of this pattern demonstrates a candidate's ability to reason about recursion, graph traversal, and optimal substructure.

OPTIMIZATION CHALLENGE

The key insight is to avoid recomputing child heights by propagating results upward in a single DFS pass, turning an exponential or quadratic brute force into a linear O(N) solution.

REAL-WORLD CONNECTION

Think of a corporate org chart: the CEO is the root, and the longest chain of management levels from CEO to the most junior employee mirrors the tree's height. In distributed tracing, the deepest span sequence reflects the maximum call depth, analogous to tree height computation.

When coding, first build an adjacency list, locate the root with a set difference, then write a clean recursive function that returns height; add a visited guard only if the input might contain cycles, but a proper tree guarantees acyclicity.

COMPLEXITY AT A GLANCE

⏱ Time:O(N)
💾 Space:O(H)

Core Theory — Why This Approach?

The problem of computing a tree's maximum height is a classic example of depth‑first recursion on hierarchical data structures. A naive solution that repeatedly scans the entire node list for each node leads to quadratic time because each subtree is recomputed from scratch, which quickly becomes infeasible for large N (10⁵+). The optimal paradigm treats the tree as a directed acyclic graph rooted at the unique root, and performs a single post‑order traversal: for each node, the height is 1 plus the maximum height among its children. This leverages the optimal substructure property—sub‑problems (heights of sub‑trees) are independent and can be solved once, then combined. By memoizing or simply propagating results upward during recursion, the algorithm runs in linear time, O(N), and uses only O(H) auxiliary stack space, where H is the tree height.

Recursion naturally mirrors the definition of height: the height of a leaf is 1, and any internal node's height is 1 + max(child heights). Implementing this with a depth‑first search (DFS) ensures each edge is visited exactly once. The adjacency list representation—mapping each node to its list of children—provides O(1) access to a node's descendants, avoiding costly searches. This approach also gracefully handles unbalanced trees, as the recursion depth adapts to the actual height rather than the total node count.

Why naive approaches fail: iterating over all nodes for each depth level or recomputing child heights repeatedly results in O(N²) time, which exceeds typical time limits for N up to 10⁵. The optimal linear solution eliminates redundant work by visiting each node a single time, making it scalable for production‑grade datasets and interview constraints.

Interview Questions on This Problem

Q1How would you compute the maximum height of a tree given only a parent‑to‑children map without an explicit root identifier?

First, identify the root by finding the node that never appears as a child (using a set difference). Then run a DFS from that root, returning 1 + max(child heights) for each node; the final return value is the tree's maximum height.

Q2In a distributed system where each service reports its downstream dependencies as a list, how can you detect the longest call chain efficiently?

Model the services as nodes in a directed acyclic graph and apply the same DFS height calculation; the longest call chain corresponds to the maximum height, computed in O(V+E) time with memoization to avoid recomputation across services.

Q3Why might a recursive solution cause a stack overflow on very deep trees, and how can you mitigate it in a coding interview?

Recursion depth equals tree height; for skewed trees with N≈10⁵, the call stack may exceed language limits. Mitigate by converting the DFS to an explicit stack (iterative post‑order) or by using tail‑recursion optimization where the language supports it.

Examples

Example 1

Input

5
1 2 2 3
2 1 4
3 0
4 1 5
5 0

Output

1

Explanation: Node 1 is the root (no parent). The longest path is 1→2→4→5, which contains 4 nodes, so the height is 4.

Example 2

Input

3
10 1 20
20 1 30
30 0

Output

1

Explanation: Root is 10. The only root‑to‑leaf chain is 10→20→30, comprising 3 nodes; therefore the height equals 3.

Example 3

Input

1
42 0

Output

1

Explanation: A single node forms a tree of height 1 because the root is also the leaf.

Constraints

  • 1 <= N <= 100000
  • Node identifiers are distinct integers in the range [1, 10^9]
  • The sum of all child counts equals N-1, guaranteeing a single connected tree
  • Recursion depth may reach N, so an iterative or tail‑recursive solution is recommended

Optimal Approach & Strategy

Perform a single depth‑first traversal from the root, returning 1 + max(child heights) for each node, achieving O(N) time.

Brute Force Approach

Repeatedly compute the height of every node by traversing its entire subtree each time, leading to O(N²) time.

Code Solutions

JavaScript Solution
Time: O(N)
function maxHeight(children, root) {
    if (!children[root] || children[root].length === 0) {
        return 1;
    }
    
    let maxChildHeight = 0;
    for (const child of children[root]) {
        const childHeight = maxHeight(children, child);
        maxChildHeight = Math.max(maxChildHeight, childHeight);
    }
    
    return 1 + maxChildHeight;
}

const fs = require('fs');
const data = fs.readFileSync(0, 'utf8').trim().split('\n');
let index = 0;

function readInt() {
    return parseInt(data[index++]);
}

const N = readInt();
const children = {};
const allNodes = new Set();
const childNodes = new Set();

for (let i = 0; i < N; i++) {
    const node = readInt();
    const C = readInt();
    const kids = [];
    for (let j = 0; j < C; j++) {
        const child = readInt();
        kids.push(child);
        childNodes.add(child);
    }
    children[node] = kids;
    allNodes.add(node);
}

let root = -1;
for (const node of allNodes) {
    if (!childNodes.has(node)) {
        root = node;
        break;
    }
}

console.log(maxHeight(children, root));

Asked in Top Tech Interviews

FlipkartAdobe

Solve in Interative Editor

Ready to test your code? Open our built-in compiler, run custom test suites, and see detailed complexity analysis reports instantly.