Welcome to Subscribe On Youtube

Formatted question description: https://leetcode.ca/all/2385.html

2385. Amount of Time for Binary Tree to Be Infected

  • Difficulty: Medium.
  • Related Topics: Tree, Depth-First Search, Breadth-First Search, Binary Tree.
  • Similar Questions: Maximum Depth of Binary Tree, Shortest Path to Get Food, All Nodes Distance K in Binary Tree.

Problem

You are given the root of a binary tree with unique values, and an integer start. At minute 0, an infection starts from the node with value start.

Each minute, a node becomes infected if:

  • The node is currently uninfected.

  • The node is adjacent to an infected node.

Return the number of minutes needed for the entire tree to be infected.

  Example 1:

Input: root = [1,5,3,null,4,10,6,9,2], start = 3
Output: 4
Explanation: The following nodes are infected during:
- Minute 0: Node 3
- Minute 1: Nodes 1, 10 and 6
- Minute 2: Node 5
- Minute 3: Node 4
- Minute 4: Nodes 9 and 2
It takes 4 minutes for the whole tree to be infected so we return 4.

Example 2:

Input: root = [1], start = 1
Output: 0
Explanation: At minute 0, the only node in the tree is infected so we return 0.

  Constraints:

  • The number of nodes in the tree is in the range [1, 105].

  • 1 <= Node.val <= 105

  • Each node has a unique value.

  • A node with a value of start exists in the tree.

Solution (Java, C++, Python)

  • /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode() {}
     *     TreeNode(int val) { this.val = val; }
     *     TreeNode(int val, TreeNode left, TreeNode right) {
     *         this.val = val;
     *         this.left = left;
     *         this.right = right;
     *     }
     * }
     */
    class Solution {
        private int max = 0;
    
        public int amountOfTime(TreeNode root, int start) {
            dfs(root, start, new Distance(-1));
            return max;
        }
    
        private int dfs(TreeNode root, int start, Distance l) {
            if (root == null) {
                return 0;
            }
            Distance ld = new Distance(-1);
            Distance rd = new Distance(-1);
            int left = dfs(root.left, start, ld);
            int right = dfs(root.right, start, rd);
            if (l.val == -1 && start == root.val) {
                max = Math.max(left, right);
                l.val = 1;
            }
            if (ld.val != -1) {
                max = Math.max(max, ld.val + right);
                l.val = ld.val + 1;
            } else if (rd.val != -1) {
                max = Math.max(max, rd.val + left);
                l.val = rd.val + 1;
            }
            return Math.max(left, right) + 1;
        }
    
        private static class Distance {
            int val;
    
            Distance(int v) {
                this.val = v;
            }
        }
    }
    
    ############
    
    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode() {}
     *     TreeNode(int val) { this.val = val; }
     *     TreeNode(int val, TreeNode left, TreeNode right) {
     *         this.val = val;
     *         this.left = left;
     *         this.right = right;
     *     }
     * }
     */
    class Solution {
        private Map<Integer, List<Integer>> g = new HashMap<>();
    
        public int amountOfTime(TreeNode root, int start) {
            dfs(root);
            Deque<Integer> q = new ArrayDeque<>();
            Set<Integer> vis = new HashSet<>();
            q.offer(start);
            int ans = -1;
            while (!q.isEmpty()) {
                ++ans;
                for (int n = q.size(); n > 0; --n) {
                    int i = q.pollFirst();
                    vis.add(i);
                    if (g.containsKey(i)) {
                        for (int j : g.get(i)) {
                            if (!vis.contains(j)) {
                                q.offer(j);
                            }
                        }
                    }
                }
            }
            return ans;
        }
    
        private void dfs(TreeNode root) {
            if (root == null) {
                return;
            }
            if (root.left != null) {
                g.computeIfAbsent(root.val, k -> new ArrayList<>()).add(root.left.val);
                g.computeIfAbsent(root.left.val, k -> new ArrayList<>()).add(root.val);
            }
            if (root.right != null) {
                g.computeIfAbsent(root.val, k -> new ArrayList<>()).add(root.right.val);
                g.computeIfAbsent(root.right.val, k -> new ArrayList<>()).add(root.val);
            }
            dfs(root.left);
            dfs(root.right);
        }
    }
    
  • # Definition for a binary tree node.
    # class TreeNode:
    #     def __init__(self, val=0, left=None, right=None):
    #         self.val = val
    #         self.left = left
    #         self.right = right
    class Solution:
        def amountOfTime(self, root: Optional[TreeNode], start: int) -> int:
            def dfs(root):
                if root is None:
                    return
                if root.left:
                    g[root.val].append(root.left.val)
                    g[root.left.val].append(root.val)
                if root.right:
                    g[root.val].append(root.right.val)
                    g[root.right.val].append(root.val)
                dfs(root.left)
                dfs(root.right)
    
            g = defaultdict(list)
            dfs(root)
            vis = set()
            q = deque([start])
            ans = -1
            while q:
                ans += 1
                for _ in range(len(q)):
                    i = q.popleft()
                    vis.add(i)
                    for j in g[i]:
                        if j not in vis:
                            q.append(j)
            return ans
    
    ############
    
    # 2385. Amount of Time for Binary Tree to Be Infected
    # https://leetcode.com/problems/amount-of-time-for-binary-tree-to-be-infected/
    
    # Definition for a binary tree node.
    # class TreeNode:
    #     def __init__(self, val=0, left=None, right=None):
    #         self.val = val
    #         self.left = left
    #         self.right = right
    class Solution:
        def amountOfTime(self, root: Optional[TreeNode], start: int) -> int:
            time = 0
            graph = defaultdict(list)
            N = 0
            
            def dfs(node):
                nonlocal N
                
                if not node: return
                
                N += 1    
                
                if node.left:
                    graph[node.left.val].append(node.val)
                    graph[node.val].append(node.left.val)
                
                if node.right:
                    graph[node.right.val].append(node.val)
                    graph[node.val].append(node.right.val)
                
                dfs(node.left)
                dfs(node.right)
            
            dfs(root)
            
            if N == 1: return 0
            
            s = [start]
            visited = defaultdict(lambda : False)
            visited[start] = True
            
            while s:
                nxt = []
                
                for node in s:
                    for nei in graph[node]:
                        if not visited[nei]:
                            visited[nei] = True
                            nxt.append(nei)
                
                time += 1
                s = nxt
            
            return time - 1
    
    
  • /**
     * Definition for a binary tree node.
     * struct TreeNode {
     *     int val;
     *     TreeNode *left;
     *     TreeNode *right;
     *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
     *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
     *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
     * };
     */
    class Solution {
    public:
        unordered_map<int, vector<int>> g;
    
        int amountOfTime(TreeNode* root, int start) {
            dfs(root);
            queue<int> q{ {start} };
            unordered_set<int> vis;
            int ans = -1;
            while (q.size()) {
                ++ans;
                for (int n = q.size(); n; --n) {
                    int i = q.front();
                    q.pop();
                    vis.insert(i);
                    for (int j : g[i]) {
                        if (!vis.count(j)) {
                            q.push(j);
                        }
                    }
                }
            }
            return ans;
        }
    
        void dfs(TreeNode* root) {
            if (!root) return;
            if (root->left) {
                g[root->val].push_back(root->left->val);
                g[root->left->val].push_back(root->val);
            }
            if (root->right) {
                g[root->val].push_back(root->right->val);
                g[root->right->val].push_back(root->val);
            }
            dfs(root->left);
            dfs(root->right);
        }
    };
    
  • /**
     * Definition for a binary tree node.
     * type TreeNode struct {
     *     Val int
     *     Left *TreeNode
     *     Right *TreeNode
     * }
     */
    func amountOfTime(root *TreeNode, start int) int {
    	g := map[int][]int{}
    	var dfs func(*TreeNode)
    	dfs = func(root *TreeNode) {
    		if root == nil {
    			return
    		}
    		if root.Left != nil {
    			g[root.Val] = append(g[root.Val], root.Left.Val)
    			g[root.Left.Val] = append(g[root.Left.Val], root.Val)
    		}
    		if root.Right != nil {
    			g[root.Val] = append(g[root.Val], root.Right.Val)
    			g[root.Right.Val] = append(g[root.Right.Val], root.Val)
    		}
    		dfs(root.Left)
    		dfs(root.Right)
    	}
    
    	dfs(root)
    	q := []int{start}
    	ans := -1
    	vis := map[int]bool{}
    	for len(q) > 0 {
    		ans++
    		for n := len(q); n > 0; n-- {
    			i := q[0]
    			q = q[1:]
    			vis[i] = true
    			for _, j := range g[i] {
    				if !vis[j] {
    					q = append(q, j)
    				}
    			}
    		}
    	}
    	return ans
    }
    
  • /**
     * Definition for a binary tree node.
     * class TreeNode {
     *     val: number
     *     left: TreeNode | null
     *     right: TreeNode | null
     *     constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
     *         this.val = (val===undefined ? 0 : val)
     *         this.left = (left===undefined ? null : left)
     *         this.right = (right===undefined ? null : right)
     *     }
     * }
     */
    
    function amountOfTime(root: TreeNode | null, start: number): number {
        const map = new Map<number, number[]>();
        const create = ({ val, left, right }: TreeNode) => {
            if (left != null) {
                map.set(val, [...(map.get(val) ?? []), left.val]);
                map.set(left.val, [...(map.get(left.val) ?? []), val]);
                create(left);
            }
            if (right != null) {
                map.set(val, [...(map.get(val) ?? []), right.val]);
                map.set(right.val, [...(map.get(right.val) ?? []), val]);
                create(right);
            }
        };
        create(root);
        const dfs = (st: number, fa: number) => {
            let res = 0;
            for (const v of map.get(st) ?? []) {
                if (v !== fa) {
                    res = Math.max(res, dfs(v, st) + 1);
                }
            }
            return res;
        };
        return dfs(start, -1);
    }
    
    

Explain:

nope.

Complexity:

  • Time complexity : O(n).
  • Space complexity : O(n).

All Problems

All Solutions