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.

Forget the word "infection" for a moment — it is just a stopwatch on distance. A node lights up at minute d exactly when it sits d edges from the start, because the fire crawls one edge per minute in every direction at once. So the whole tree is on fire the moment the furthest node catches. The answer is simply the distance to that farthest node.

text
             1
            / \
           5   3   <-- start (minute 0)
            \  / \
             4 10 6
            / \
           9  2

  distances from 3:  10,6 -> 1     1 -> 1     5 -> 2     4 -> 3     9,2 -> 4
  farthest is 9 and 2, four edges away  ->  answer = 4

The catch is in that little diagram: the fire runs up from 3 to 1, then back down a whole different branch to reach 9 and 2. This is not tree depth measured from the root — it is spread outward from a node sitting anywhere in the tree.

The pointers only go down — add the missing half

Every node knows its children but not its parent. So from the start we can burn downward but never climb up to 1. Yet the edge between a parent and child is really two-way — we are just missing one direction. So add it: walk the tree once and write down each node's parent in a map. Now every node has up to three neighbours — left child, right child, and parent.

text
tree pointers (down only)      +  parent map  =  fire can go both ways

        1                            parent: 5->1, 3->1, 4->5,
       / \                                   9->4, 2->4, 10->3, 6->3
      5   3      start = 3           so from 3 the fire reaches
       \  / \                        10, 6 (children) AND 1 (parent)
        4 ...

Once edges point both ways, the tree is really an undirected graph, and "how far is the farthest node" is the standard graph move: spread outward from the start in rings — everything 1 edge away, then everything 2 away — and keep going until the tree is exhausted. That is breadth-first search.

One duty comes with the two-way edges: you can walk straight back where you came from (3 → 1 → 3) and loop forever. So keep a visited set and admit each node only once, on first arrival. BFS always reaches a node by its shortest path first, so that first arrival is at its true distance — which makes blocking every later arrival both safe and necessary.

Count the rings — the answer is how many minutes passed

Ring 0 is the start alone, on fire at minute 0 — no time has passed yet. Ring 1 is on fire at minute 1, ring 2 at minute 2. So the answer is the minute of the last non-empty ring. Watch it run, start = 3:

text
minute 0:  [3]           burn -> children 10, 6 and parent 1
minute 1:  [10, 6, 1]    10,6 add nothing new.  1 adds its child 5 (3 already seen)
minute 2:  [5]           5 adds its child 4
minute 3:  [4]           4 adds its children 9, 2
minute 4:  [9, 2]        both leaves, nothing new  ->  queue empties

last ring was minute 4  ->  answer = 4
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    # find 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 = one ring
        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 Note — the off-by-one is the whole game. minutes starts at -1 so that processing the first ring (the start by itself) bumps it to 0. Start it at 0 instead and every answer is one too big, including the single-node tree whose correct answer is 0. The clean way to never trip: fix the counter's meaning before the loop — here it is "the minute the ring being processed caught fire", which is 0 for the start.

The visited set is not an optimisation — it is what keeps distances correct. Drop it and node 1 would immediately re-enqueue node 3, which reappears a ring later at the wrong distance and re-burns its whole subtree with inflated numbers. Wrong answer, not merely a slow one.

Cost, and the family it belongs to

Mapping parents visits every node once; BFS admits every node once. Total: O(N) time, O(N) space for the map, the visited set, and the queue. On the 10⁵-node limit a chain could push the recursive parent-mapping 10⁵ frames deep, so an iterative walk with an explicit stack is the safe version there.

Step back and notice how little was actually new. 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, shortest steps in a maze, and a rumour spreading through a social graph. Build the neighbour relation the question implies, expand outward in layers, and read off the last layer reached — and the tree is 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