Minimum time required to infect all the nodes of Binary tree
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: 3Input:
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.
- Check if the current node’s parent exists in the tree and is not infected yet.
- Increment the result by 1. (i.e, the infection has already spread by the above steps for this time.)
- Iterate over the size of the queue and do the following:
- 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. |
3
Time Complexity: O(N), where N is the number of nodes in the binary tree.
Auxiliary Space: O(N)
Please Login to comment...