Algorithm

Amount of Time for Binary Tree to Be Infected

Trees Pattern

Amount of Time for Binary Tree to Be Infected

An infection begins at minute 0 at the node whose value is start. Each minute, every already-infected node infects all of its immediate neighbours — its parent and both of its children. Return the number of minutes until every node in the tree is infected. If the tree has a single node, the answer is 0, since it is infected from the outset.

CONSTRAINTS
  • The number of nodes is in the range [1, 10⁵]
  • 1 <= Node.val <= 10⁵, and all values are unique
  • start is guaranteed to be the value of a node in the tree
  • Infection spreads to parents as well as to children
EXAMPLE 1
Input: root = [1,5,3,null,4,10,6,9,2], start = 3
Output: 4
Minute 1 infects 1, 10 and 6; minute 2 reaches 5; minute 3 reaches 4; minute 4 reaches 9 and 2. The last nodes to fall are four steps from the start.
EXAMPLE 2
Input: root = [1], start = 1
Output: 0
The only node is infected at minute 0, so no time passes. Answering 1 by counting the first round anyway is the standard off-by-one here.
EXAMPLE 3
Input: root = [1,2,null,3,null,4], start = 4
Output: 3
Starting at the deep end of a chain, the infection can only travel upward, taking one minute per link.
EXAMPLE 4
Input: root = [1,2,null,3,null,4], start = 3
Output: 2
Starting in the middle, the infection spreads both ways at once — down to 4 in one minute, up through 2 to 1 in two. The answer is the longer of the two directions, not their sum.
Does the infection travel upward?
Yes, to the parent as well as to both children, which is the whole reason this is not a simple depth calculation.
What is the answer for a single node?
0. It is infected at minute 0 and there is nothing else to reach.
Is the start given as a value or a node?
As a value, so you must locate the node first. The values are unique, which makes that lookup well defined.
Is the answer just the tree's height?
No. Height is measured from the root, while this is measured from an arbitrary start and may run upward and then down another branch.

Strip away the story and this is a question about distance. A node becomes infected at minute d exactly when its shortest path from the start node is d edges long — the infection advances one edge per minute in every direction at once, so nothing can arrive faster than the shortest path and nothing arrives later. The whole tree is infected when the furthest node falls, so the answer is:

text
answer = max over all nodes v of  distance(start, v)

Since edges are travelled in both directions, this is the same setting as All Nodes Distance K: the tree's pointers give only downward links, so the parent edges have to be reconstructed before any of this can be computed. Build a map from each node to its parent in one walk, and every node then has up to three neighbours.

The same rings, a different question

Distance K expanded outward in rings and returned ring number k. Here we expand in exactly the same way and simply keep going until nothing is left, then report how many rings we completed. That count is the largest distance from the start to anything, which is the answer.

The only real difficulty is the off-by-one, so pin it down precisely. Ring 0 is the start node alone, and it is infected at minute 0 — no time has passed. Ring 1 is infected at minute 1. So the answer equals the index of the last non-empty ring, which is one less than the number of rings processed.

python
parent, start_node = {}, None
def map_parents(node, par):
    global start_node
    if node is None: return
    parent[node] = par
    if node.val == start: start_node = node    # locate the start while mapping
    map_parents(node.left, node)
    map_parents(node.right, node)
map_parents(root, None)

queue, seen, minutes = deque([start_node]), {start_node}, -1
while queue:
    minutes += 1                               # ring 0 costs 0 minutes
    for _ in range(len(queue)):                # frozen ring size
        node = queue.popleft()
        for nxt in (node.left, node.right, parent[node]):
            if nxt and nxt not in seen:
                seen.add(nxt)
                queue.append(nxt)
return minutes
Crucial Noteminutes starts at -1 so that processing the first ring — the start node by itself — brings it to 0. Start it at 0 instead and every answer is one too large, including the single-node case where the correct answer is 0. The cleanest way to keep this straight is to fix the meaning of the counter before writing the loop: here it is the minute at which the ring currently being processed became infected, which is 0 for the start node. Both this problem and Distance K count rings; they differ only in whether you stop at a chosen ring or report the last one.

The visited set carries the same weight as before. Once parent edges exist the structure is an undirected graph, so without it the infection would bounce back and forth across a single edge forever, and nodes would be counted at the wrong distances.

Worked example:root 1, children 5 and 3; 5 has right child 4; 4 has children 9 and 2; 3 has children 10 and 6. Start = 3
- Minute 0: ring holds [3]. Expand — children 10 and 6, and parent 1. All enqueued.
- Minute 1: ring holds [10, 6, 1]. The leaves 10 and 6 add nothing new (their parent 3 is seen). Node 1 adds its left child 5; its right child 3 is already seen and it has no parent.
- Minute 2: ring holds [5]. It adds its right child 4.
- Minute 3: ring holds [4]. It adds its children 9 and 2.
- Minute 4: ring holds [9, 2]. Both are leaves with nothing unseen around them, so no ring follows.
- The queue empties with minutes = 4.

Notice that the infection travelled up through 1 and then down a completely different branch to reach 9 and 2. Measuring depth from the root would have given a different — and wrong — number.

Cost, and the family

Mapping parents visits every node once, and the search admits every node once, so the total is O(N) time and O(N) space for the map, the visited set and the queue. At the 10⁵-node limit the recursive parent mapping could go 10⁵ frames deep on a chain, so an iterative walk with an explicit stack — the technique from Iterative Traversals — is worth mentioning.

Step back and notice how little was new here. Once the parent edges exist, the tree is a graph, and this is the classic "how long does something spread through a network" question, answered by counting breadth-first layers. The same shape solves rotting oranges in a grid, minimum steps in a maze, and the spread of a rumour through a social graph. Build the neighbour relation the question implies, expand outward in layers, and read off either the layer you were asked about or the last one reached — and the tree becomes just one more graph.

Interactive Strategy Visualization

Nodes at Distance K

Multi-Directional BFS from Target

351620874
Target: Node 5, K = 2
Starting BFS from target node...

Key Mechanics

  • Parent Pointers: First, build a map of parent references to enable upward traversal.
  • Multi-Directional: BFS explores left, right, and parent neighbors from the target.
  • Distance Tracking: Each BFS level represents distance +1 from the target.
BFS WAVESTEP 0/4
Initialize BFS from target node 5.
USE CASE

Real-World Applications

This pattern powers social network friend suggestions (find users K connections away), organizational hierarchy queries (employees K levels from a manager), and network routing (nodes K hops from a source). The parent-pointer technique transforms trees into undirected graphs for bidirectional exploration.

Strategy

Focus on the recursive nature of trees: solve for subtrees and combine results at the root.

"Divide and Conquer: Subproblem → Recurrence → Result"

Height From Root (Wrong Reference Point)
O(N) Time · O(N) Space Parent Map Plus BFS Layer Count