Skip to content
Related Articles
Open in App
Not now

Related Articles

Minimum time required to infect all the nodes of Binary tree

Improve Article
Save Article
  • Difficulty Level : Basic
  • Last Updated : 26 Dec, 2022
Improve Article
Save Article

Given a binary tree and a node start that is initially infected. For every second, neighbours of an infected node get infected. The task is to find the minimum time in which the whole tree will be infected.

Examples:

Input:
         10
      /     \
 12      13
        /       \
    14        15
   /  \        /   \
21 22  23  24
Start = 14
Output: 3

Input: 
       3
    /    \
  4      1
            \
             2
Start = 1
Output: 2

An approach using BFS (Breadth-first search):

The idea to solve this problem is by doing the BFS (breadth-first search) algorithm on the tree,  

Starts from the given special node “start”. During the BFS make all adjacent node infected. Keep counting the time in result, where we have visited all the node. 

One problem while infecting the adjacent node is that we can easily know the node’s children (left child or right child) which is adjacent but we can’t know that node’s parent directly. So, to overcome this problem we have to generate a parent-node relationship into some data structure, there we can keep track to node’s parent.

Follow the steps below to implement the above idea:

  • Store parent-child relations for each node in the parent array. (i.e, keeping track of the parent of any node)
  • Find the actual node “node” of a given special node start in the tree.
  • Create a queue for performing the BFS and an array visited to keep track of which node has already been infected.
  • Do BFS (Breadth-first search) by initially storing the “node” in the queue and making this “node” visited.
  • Do the following while queue size is greater than zero.
    • Iterate over the size of the queue and do the following:
      • Check if the current node’s parent exists in the tree and is not infected yet.
        • Push into the queue and make it visited to show it’s infected now.
      • Check if the current node’s left child exists in the tree and is not infected yet.
        • Push into the queue and make it visited to show it’s infected now.
      • Check if the current node’s right exists in the tree and is not infected yet.
        • Push into the queue and make it visited to show it’s infected now.
    • Increment the result by 1. (i.e, the infection has already spread by the above steps for this time.)
  • Return the result.

Below is the implementation of the above approach.

C++




// C++ code for the above approach:
 
#include <bits/stdc++.h>
using namespace std;
 
// A Tree node
struct Node {
    int val;
    struct Node *left, *right;
};
 
// Utility function to create a new node
Node* newNode(int val)
{
    Node* temp = new Node;
    temp->val = val;
    temp->left = temp->right = NULL;
    return (temp);
}
 
// "node" will store the actual Tree node
// of special node "start".
Node* node = NULL;
 
// Function for generating
// parent-root relationship
void findParent(Node* root, Node* p, vector<Node*>& parent,
                int start)
{
    if (root == NULL)
        return;
 
    // Store parent of current node
    parent[root->val] = p;
    if (root->val == start) {
        node = root;
    }
 
    findParent(root->left, root, parent, start);
    findParent(root->right, root, parent, start);
}
 
// Function to return the minimum amount
// of time require to infect all the
// nodes of binary tree
int amountOfTime(Node* root, int start)
{
 
    vector<Node*> parent(100005, NULL);
    findParent(root, NULL, parent, start);
 
    vector<bool> visited(100005, false);
 
    queue<Node*> q;
 
    // Push special tree node into the
    // queue and make it visited.
    q.push(node);
    visited[start] = true;
 
    // This store the minimum time require
    // to infect all the tree node.
    int result = -1;
 
    while (q.size() > 0) {
        int n = q.size();
 
        for (int i = 0; i < n; i++) {
            auto curr = q.front();
            int currNode = curr->val;
            q.pop();
 
            // Check if parent of currNode
            // exist and not visited yet
            // then push this parent of
            // current node into queue.
            if (parent[currNode] != NULL
                && visited[parent[currNode]->val]
                       == false) {
                visited[parent[currNode]->val] = true;
                q.push(parent[currNode]);
            }
 
            // Check if current node left
            // child exist and not
            // visited yet.
            if (curr->left
                && visited[curr->left->val] == false) {
                visited[curr->left->val] = true;
                q.push(curr->left);
            }
 
            // Check if current node right
            // child exist and not
            // visited yet.
            if (curr->right
                && visited[curr->right->val] == false) {
                visited[curr->right->val] = true;
                q.push(curr->right);
            }
        }
 
        // Increment the time
        result++;
    }
 
    // Return the result.
    return result;
}
 
// Driver Code
int main()
{
    /*      10
           /  \
          12  13
              / \
             14 15
            / \ / \
          21 22 23 24
 
        Let us create Binary Tree as shown
        above */
 
    Node* root = newNode(10);
    root->left = newNode(12);
    root->right = newNode(13);
 
    root->right->left = newNode(14);
    root->right->right = newNode(15);
 
    root->right->left->left = newNode(21);
    root->right->left->right = newNode(22);
    root->right->right->left = newNode(23);
    root->right->right->right = newNode(24);
 
    int start = 14;
 
    // Function call
    int result = amountOfTime(root, start);
    cout << result << endl;
 
    return 0;
}


Java




// Java code for the above approach
import java.io.*;
import java.util.*;
 
class Node {
  int val;
  Node left, right;
 
  public Node(int item)
  {
    val = item;
    left = right = null;
  }
}
 
class GFG {
  static Node node = null;
 
  // Function for generating
  // parent-root relationship
  static void findParent(Node root, Node p, Node[] parent,
                         int start)
  {
    if (root == null)
      return;
 
    // Store parent of current node
    parent[root.val] = p;
 
    if (root.val == start) {
      node = root;
    }
 
    findParent(root.left, root, parent, start);
    findParent(root.right, root, parent, start);
  }
 
  // Function to return the minimum amount
  // of time require to infect all the
  // nodes of binary tree
  static int amountOfTime(Node root, int start)
  {
 
    Node[] parent = new Node[100005];
    findParent(root, null, parent, start);
 
    boolean[] visited = new boolean[100005];
    Arrays.fill(visited, false);
 
    Queue<Node> q = new LinkedList<>();
 
    // add special tree node into the
    // queue and make it visited.
    q.add(node);
    visited[start] = true;
 
    // This store the minimum time require
    // to infect all the tree node.
    int result = -1;
 
    while (q.size() > 0) {
      int n = q.size();
 
      for (int i = 0; i < n; i++) {
        Node curr = q.peek();
        int currNode = curr.val;
        q.remove();
 
        // Check if parent of currNode
        // exist and not visited yet
        // then add this parent of
        // current node into queue.
        if (parent[currNode] != null
            && visited[parent[currNode].val]
            == false) {
          visited[parent[currNode].val] = true;
          q.add(parent[currNode]);
        }
 
        // Check if current node left
        // child exist and not
        // visited yet.
        if (curr.left!=null
            && visited[curr.left.val] == false) {
          visited[curr.left.val] = true;
          q.add(curr.left);
        }
 
        // Check if current node right
        // child exist and not
        // visited yet.
        if (curr.right!=null
            && visited[curr.right.val] == false) {
          visited[curr.right.val] = true;
          q.add(curr.right);
        }
      }
 
      // Increment the time
      result++;
    }
 
    // Return the result.
    return result;
  }
 
  public static void main(String[] args)
  {
    /*      10
           /  \
          12  13
              / \
             14 15
            / \ / \
          21 22 23 24
 
        Let us create Binary Tree as shown
        above */
 
    Node root = new Node(10);
    root.left = new Node(12);
    root.right = new Node(13);
 
    root.right.left = new Node(14);
    root.right.right = new Node(15);
 
    root.right.left.left = new Node(21);
    root.right.left.right = new Node(22);
    root.right.right.left = new Node(23);
    root.right.right.right = new Node(24);
 
    int start = 14;
 
    // Function call
    int result = amountOfTime(root, start);
    System.out.println(result);
  }
}
 
// This code is contributed by ishankhandelwals.


Python3




# Python program for the above approach
# A Tree node
class Node:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right
 
# Utility function to create a new node
def newNode(val):
    return Node(val)
 
 
# "node" will store the actual Tree node
# of special node "start".
node = None
 
# Function for generating
# parent-root relationship
 
 
def findParent(root, p, parent, start):
    if not root:
        return
    # Store parent of current node
    parent[root.val] = p
    if root.val == start:
        global node
        node = root
    findParent(root.left, root, parent, start)
    findParent(root.right, root, parent, start)
 
# Function to return the minimum amount
# of time require to infect all the
# nodes of binary tree
 
 
def amountOfTime(root, start):
    parent = [None] * 100005
    findParent(root, None, parent, start)
 
    visited = [False] * 100005
 
    q = []
 
    # Push special tree node into the
    # queue and make it visited.
    q.append(node)
    visited[start] = True
 
    # This store the minimum time require
    # to infect all the tree node.
    result = -1
 
    while len(q) > 0:
        n = len(q)
        for i in range(n):
            curr = q.pop(0)
            currNode = curr.val
 
            # Check if parent of currNode
            # exist and not visited yet
            # then push this parent of
            # current node into queue.
            if parent[currNode] and not visited[parent[currNode].val]:
                visited[parent[currNode].val] = True
                q.append(parent[currNode])
 
            # Check if current node left
            # child exist and not
            # visited yet.
            if curr.left and not visited[curr.left.val]:
                visited[curr.left.val] = True
                q.append(curr.left)
 
            # Check if current node right
            # child exist and not
            # visited yet.
            if curr.right and not visited[curr.right.val]:
                visited[curr.right.val] = True
                q.append(curr.right)
 
        # Increment the time
        result += 1
 
    # Return the result.
    return result
 
 
# Driver Code
 
    """
      10
     /  \
    12  13
        / \
       14 15
      / \ / \
    21 22 23 24
 
    Let us create Binary Tree as shown
    above
    """
 
 
root = newNode(10)
root.left = newNode(12)
root.right = newNode(13)
 
root.right.left = newNode(14)
root.right.right = newNode(15)
 
root.right.left.left = newNode(21)
root.right.left.right = newNode(22)
root.right.right.left = newNode(23)
root.right.right.right = newNode(24)
 
start = 14
 
# Function call
result = amountOfTime(root, start)
print(result)
 
# This code is contributed by Potta Lokesh


C#




// C# code for the above approach:
using System;
using System.Collections.Generic;
 
public class Node {
  public int val;
  public Node left, right;
 
  public Node(int item)
  {
    val = item;
    left = right = null;
  }
}
 
public class GFG {
  // "node" will store the actual Tree node
  // of special node "start".
  public Node node;
 
  // Function for generating
  // parent-root relationship
  public void findParent(Node root, Node p, int[] parent,
                         int start)
  {
    if (root == null)
      return;
 
    // Store parent of current node
    parent[root.val] = p.val;
    if (root.val == start) {
      node = root;
    }
 
    findParent(root.left, root, parent, start);
    findParent(root.right, root, parent, start);
  }
 
  // Function to return the minimum amount
  // of time require to infect all the
  // nodes of binary tree
  public int amountOfTime(Node root, int start)
  {
    int[] parent = new int[100005];
    findParent(root, new Node(0), parent, start);
 
    bool[] visited = new bool[100005];
 
    Queue<Node> q = new Queue<Node>();
 
    // Push special tree node into the
    // queue and make it visited.
    q.Enqueue(node);
    visited[start] = true;
 
    // This store the minimum time require
    // to infect all the tree node.
    int result = -1;
 
    while (q.Count > 0) {
      int n = q.Count;
      for (int i = 0; i < n; i++) {
        var curr = q.Peek();
        int currNode = curr.val;
        q.Dequeue();
 
        // Check if parent of currNode
        // exist and not visited yet
        // then push this parent of
        // current node into queue.
        if (parent[currNode] != 0
            && visited[parent[currNode]] == false) {
          visited[parent[currNode]] = true;
          q.Enqueue(new Node(parent[currNode]));
        }
 
        // Check if current node left
        // child exist and not
        // visited yet.
        if (curr.left != null
            && visited[curr.left.val] == false) {
          visited[curr.left.val] = true;
          q.Enqueue(curr.left);
        }
 
        // Check if current node right
        // child exist and not
        // visited yet.
        if (curr.right != null
            && visited[curr.right.val] == false) {
          visited[curr.right.val] = true;
          q.Enqueue(curr.right);
        }
      }
      // Increment the time
      result++;
    }
 
    // Return the result.
    return result;
  }
 
  // Driver Code
  public static void Main(String[] args)
  {
    /*      10
               /  \
              12  13
                  / \
                 14 15
                / \ / \
              21 22 23 24
 
            Let us create Binary Tree as shown
            above */
 
    Node root = new Node(10);
    root.left = new Node(12);
    root.right = new Node(13);
 
    root.right.left = new Node(14);
    root.right.right = new Node(15);
 
    root.right.left.left = new Node(21);
    root.right.left.right = new Node(22);
    root.right.right.left = new Node(23);
    root.right.right.right = new Node(24);
 
    int start = 14;
 
    // Function call
    int result
      = new GFG().amountOfTime(root, start);
    Console.WriteLine(result);
  }
}
 
// This code is contributed by ishankhandelwals.


Javascript




// JS code
class Node
{
    constructor(item)
    {
        this.item = item;
        this.left = this.right = null;
    }
}
var node=null;
var item=null;
function findParent(root, p, parent,start)
{
if (root == null)
    return;
 
// Store parent of current node
parent[root.item] = p;
if (root.item == start) {
node = root;
}
 
findParent(root.left, root, parent, start);
findParent(root.right, root, parent, start);
}
 
 
function amountOfTime(root,start)
{
    let parent = new Array(100005);
    parent.fill(null);
 
    findParent(root, null, parent, start);
 
    let visited=new Array(100005);
    visited.fill(false);
 
    let q=[];
 
    // Push special tree node into the
    // queue and make it visited.
    q.push(node);
    visited[start] = true;
 
    // This store the minimum time require
    // to infect all the tree node.
    let result = -1;
 
    while (q.length > 0) {
        let n = q.length;
 
        for (let i = 0; i < n; i++) {
            let curr = q[0];
            let currNode = curr.item;
            q.shift();
 
            // Check if parent of currNode
            // exist and not visited yet
            // then push this parent of
            // current node into queue.
            if (parent[currNode] != null
                && visited[parent[currNode].item]
                       == false) {
                visited[parent[currNode].item] = true;
                q.push(parent[currNode]);
            }
 
            // Check if current node left
            // child exist and not
            // visited yet.
            if (curr.left
                && visited[curr.left.item] == false) {
                visited[curr.left.item] = true;
                q.push(curr.left);
            }
 
            // Check if current node right
            // child exist and not
            // visited yet.
            if (curr.right
                && visited[curr.right.item] == false) {
                visited[curr.right.item] = true;
                q.push(curr.right);
            }
        }
 
        // Increment the time
        result++;
    }
 
    // Return the result.
    return result;
}
 
 
// Driver Code
    /*      10
           /  \
          12  13
              / \
             14 15
            / \ / \
          21 22 23 24
 
        Let us create Binary Tree as shown
        above */
 
    let root = new Node(10);
    root.left = new Node(12);
    root.right = new Node(13);
 
    root.right.left = new Node(14);
    root.right.right = new Node(15);
 
    root.right.left.left = new Node(21);
    root.right.left.right = new Node(22);
    root.right.right.left = new Node(23);
    root.right.right.right = new Node(24);
 
    let start = 14;
 
    // Function call
    let result = amountOfTime(root, start);
    console.log(result);
     
    // This code is contributed by ishankhandlwals.


Output

3

Time Complexity: O(N), where N is the number of nodes in the binary tree.
Auxiliary Space: O(N)


My Personal Notes arrow_drop_up
Related Articles

Start Your Coding Journey Now!