Amount of Time for Binary Tree to Be Infected

medium tree bfs dfs

Problem

Given the root of a binary tree with unique values and the value of a starting node, an infection begins at that node. Each minute the infection spreads from every infected node to all of its directly connected neighbors (its children and its parent) that are not yet infected. Return the number of minutes it takes for every node in the tree to become infected.

Inputtree = [1,5,3,null,4,10,6,9,2], start = 3
Output4
The farthest node from 3 is reached in 4 minutes: 3 → 1 → 5 → 4 → 9 (or 2). All other nodes are infected sooner.

from collections import deque
def amountOfTime(root, start):
    parent = {}
    def dfs(node, par):
        if not node: return
        parent[node] = par
        dfs(node.left, node); dfs(node.right, node)
    dfs(root, None)
    startNode = next(n for n in parent if n.val == start)
    seen = {startNode}
    q = deque([startNode])
    minutes = -1
    while q:
        minutes += 1
        for _ in range(len(q)):
            cur = q.popleft()
            for nb in (cur.left, cur.right, parent[cur]):
                if nb and nb not in seen:
                    seen.add(nb); q.append(nb)
    return minutes
function amountOfTime(root, start) {
  const parent = new Map();
  (function dfs(node, par) {
    if (!node) return;
    parent.set(node, par);
    dfs(node.left, node); dfs(node.right, node);
  })(root, null);
  let startNode = null;
  for (const n of parent.keys()) if (n.val === start) startNode = n;
  const seen = new Set([startNode]);
  let q = [startNode], minutes = -1;
  while (q.length) {
    minutes++;
    const next = [];
    for (const cur of q) {
      for (const nb of [cur.left, cur.right, parent.get(cur)]) {
        if (nb && !seen.has(nb)) { seen.add(nb); next.push(nb); }
      }
    }
    q = next;
  }
  return minutes;
}
class Solution {
    Map<TreeNode, TreeNode> parent = new HashMap<>();
    TreeNode startNode = null;
    public int amountOfTime(TreeNode root, int start) {
        dfs(root, null, start);
        Set<TreeNode> seen = new HashSet<>(); seen.add(startNode);
        Deque<TreeNode> q = new ArrayDeque<>(); q.offer(startNode);
        int minutes = -1;
        while (!q.isEmpty()) {
            minutes++;
            int sz = q.size();
            for (int i = 0; i < sz; i++) {
                TreeNode cur = q.poll();
                for (TreeNode nb : new TreeNode[]{ cur.left, cur.right, parent.get(cur) }) {
                    if (nb != null && seen.add(nb)) q.offer(nb);
                }
            }
        }
        return minutes;
    }
    void dfs(TreeNode n, TreeNode p, int start) {
        if (n == null) return;
        parent.put(n, p);
        if (n.val == start) startNode = n;
        dfs(n.left, n, start); dfs(n.right, n, start);
    }
}
int amountOfTime(TreeNode* root, int start) {
    unordered_map<TreeNode*, TreeNode*> parent;
    TreeNode* startNode = nullptr;
    function<void(TreeNode*, TreeNode*)> dfs = [&](TreeNode* n, TreeNode* p) {
        if (!n) return;
        parent[n] = p;
        if (n->val == start) startNode = n;
        dfs(n->left, n); dfs(n->right, n);
    };
    dfs(root, nullptr);
    unordered_set<TreeNode*> seen{startNode};
    queue<TreeNode*> q; q.push(startNode);
    int minutes = -1;
    while (!q.empty()) {
        minutes++;
        int sz = (int)q.size();
        for (int i = 0; i < sz; i++) {
            TreeNode* cur = q.front(); q.pop();
            for (TreeNode* nb : { cur->left, cur->right, parent[cur] }) {
                if (nb && !seen.count(nb)) { seen.insert(nb); q.push(nb); }
            }
        }
    }
    return minutes;
}
Time: O(n) Space: O(n)