# Maximum time required for all patients to get infected

• Difficulty Level : Hard
• Last Updated : 25 Aug, 2021

Given a matrix arr[][], consisting of only 0, 1, and 2, that represents an empty ward, an uninfected patient, and an infected patient respectively. In one unit of time, an infected person at index (i, j) can infect an uninfected person adjacent to it i.e., at index (i – 1, j), (i + 1, j), (i, j – 1), and (i, j + 1). The task is to find the minimum amount of time required to infect all the patients. If it is impossible to infect all the patients, then print “-1”.

Examples:

Input: arr[][] = {{2, 1, 0, 2, 1}, {1, 0, 1, 2, 1}, {1, 0, 0, 2, 1}}
Output: 2
Explanation:
At time t = 1: The patients at positions {0, 0}, {0, 3}, {1, 3} and {2, 3} will infect patient at {{0, 1}, {1, 0}, {0, 4}, {1, 2}, {1, 4}, {2, 4}} during 1st unit time.
At time t = 2: The patient at {1, 0} will get infected and will infect patient at {2, 0}.

After the above time intervals all the uninfected patients are infected. Therefore, the total amount of time required is 2.

Input: arr[][] = {{2, 1, 0, 2, 1}, {0, 0, 1, 2, 1}, {1, 0, 0, 2, 1}}
Output: -1

## Recommended: Please solve it on “PRACTICE” first, before moving on to the solution.

Approach: The given problem can be solved by using BFS Traversal on the 2D matrix. Follow the steps below to solve the given problem:

• Initialize a 2D array, say timeofinfection[][] with -1, such that timeofinfection[i][j] stores the time when the patient at index (i, j) was infected.
• Initialize a queue to store indices of infected patients and their time of infection.
• Traverse the given matrix arr[][] and perform the following operations:
• If the value at cell (i, j) is 2, then push that cell into the queue with the time of infection as 0 i.e., {i, j, 0}.
• Iterate until the queue is non-empty and perform the following steps:
• Pop the front element of the queue and store it in a variable, say current.
• From the current popped cell (i, j), if the adjacent cell has an infected person which is unvisited, then push the index of the adjacent cell with (1 + time of infection of the current popped cell) into the queue.
• After completing the above steps, if all the infected persons are visited, i.e. the time of infection of all the infected persons is non-negative, then print the maximum element present in the matrix timeofinfection[][] as the maximum unit of time required to infect all the patients.
• Otherwise, print “-1”.

Below is the implementation of the above approach:

## C++

 // C++ program for the above approach #include using namespace std;   // Direction arrays vector > direction     = { { 1, 0 }, { 0, -1 }, { -1, 0 }, { 0, 1 } };   // Function to find the maximum time // required for all patients to get infected int maximumTime(vector > arr) {     // Stores the number of rows     int n = arr.size();       // Stores the number of columns     int m = arr[0].size();       // Stores the time of infection     // of the patient at index (i, j)     int timeofinfection[n][m];       // Stores index and time of     // infection of infected persons     queue, int> > q;       // Traverse the matrix     for (int i = 0; i < n; i++) {         for (int j = 0; j < m; j++) {               // Set the cell as unvisited             timeofinfection[i][j] = -1;               // If the current patient             // is already infected             if (arr[i][j] == 2) {                   // Push the index and time of                 // infection of current patient                 q.push({ { i, j }, 0 });                 timeofinfection[i][j] = 0;             }         }     }       // Iterate until queue becomes empty     while (!q.empty()) {         // Stores the front element of queue         pair, int> current             = q.front();           // Pop out the front element         q.pop();           // Check for all four         // adjacent indices         for (auto it : direction) {               // Find the index of the             // adjacent cell             int i = current.first.first                     + it.first;             int j = current.first.second                     + it.second;               // If the current adjacent             // cell is invalid or it             // contains an infected patient             if (i < 0 || j < 0 || i >= n                 || j >= m || arr[i][j] != 1                 || timeofinfection[i][j] != -1) {                   // Continue to the next                 // neighbouring cell                 continue;             }               // Push the infected             // neighbour into queue             q.push({ { i, j },                      current.second + 1 });             timeofinfection[i][j]                 = current.second + 1;         }     }       // Stores the maximum time     int maxi = INT_MIN;       // Stores if any uninfected     // patient exists or not     int flag = 0;       // Traverse the matrix     for (int i = 0; i < n; i++) {         for (int j = 0; j < m; j++) {             // If no patient is             // present at index (i, j)             if (arr[i][j] != 1)                 continue;               // If an uninfected patient             // is present at index (i, j)             if (arr[i][j] == 1                 && timeofinfection[i][j] == -1) {                 // Set flag as true                 flag = 1;                 break;             }               // Update the maximum time of infection             maxi = max(maxi, timeofinfection[i][j]);         }     }       // If an uninfected patient is present     if (flag)         return -1;       // Return the final result     return maxi; }   // Driver Code int main() {     vector > arr         = { { 2, 1, 0, 2, 1 },             { 1, 0, 1, 2, 1 },             { 1, 0, 0, 2, 1 } };     cout << maximumTime(arr);       return 0; }

## Java

 // Java program for the above approach import java.util.*;   class GFG {       static class pair {     int first, second, third;           pair(int first,int second,int third)     {          this.first = first;          this.second = second;          this.third = third;     } }          // Direction arrays static int[][] direction = { { 1, 0 }, { 0, -1 },                              { -1, 0 }, { 0, 1 } };   // Function to find the maximum time // required for all patients to get infected static int maximumTime(int[][] arr) {           // Stores the number of rows     int n = arr.length;       // Stores the number of columns     int m = arr[0].length;       // Stores the time of infection     // of the patient at index (i, j)     int[][] timeofinfection = new int[n][m];       // Stores index and time of     // infection of infected persons     Queue q = new LinkedList<>();       // Traverse the matrix     for(int i = 0; i < n; i++)     {         for(int j = 0; j < m; j++)         {               // Set the cell as unvisited             timeofinfection[i][j] = -1;               // If the current patient             // is already infected             if (arr[i][j] == 2)             {                                   // Push the index and time of                 // infection of current patient                 q.add(new pair(i, j, 0));                 timeofinfection[i][j] = 0;             }         }     }       // Iterate until queue becomes empty     while (!q.isEmpty())     {                   // Stores the front element of queue         pair current = q.peek();           // Pop out the front element         q.poll();           // Check for all four         // adjacent indices         for(int[] it : direction)         {                           // Find the index of the             // adjacent cell             int i = current.first + it[0];             int j = current.second + it[1];               // If the current adjacent             // cell is invalid or it             // contains an infected patient             if (i < 0 || j < 0 || i >= n ||                j >= m || arr[i][j] != 1 ||                timeofinfection[i][j] != -1)             {                   // Continue to the next                 // neighbouring cell                 continue;             }               // Push the infected             // neighbour into queue             q.add(new pair(i, j ,                            current.second + 1 ));             timeofinfection[i][j] = current.third + 1;         }     }       // Stores the maximum time     int maxi = Integer.MIN_VALUE;       // Stores if any uninfected     // patient exists or not     int flag = 0;       // Traverse the matrix     for(int i = 0; i < n; i++)     {         for(int j = 0; j < m; j++)         {                           // If no patient is             // present at index (i, j)             if (arr[i][j] != 1)                 continue;               // If an uninfected patient             // is present at index (i, j)             if (arr[i][j] == 1 && timeofinfection[i][j] == -1)             {                                   // Set flag as true                 flag = 1;                 break;             }               // Update the maximum time of infection             maxi = Math.max(maxi, timeofinfection[i][j]);         }     }       // If an uninfected patient is present     if (flag == 1)         return -1;       // Return the final result     return maxi; }   // Driver code public static void main(String[] args) {     int[][] arr = { { 2, 1, 0, 2, 1 },                     { 1, 0, 1, 2, 1 },                     { 1, 0, 0, 2, 1 } };     System.out.print(maximumTime(arr)); } }   // This code is contributed by offbeat



## Python

 # function to traverse to nearby possible directions def bfs(i, j, mat, time):     # marking position as visited     mat[i][j] = 0   # stack to store positions that got infected in one unit time     stack = []   # direction arrays     row = [-1, 0, 0, 1]     col = [0, -1, 1, 0]   # traversing to nearby uninfected beds     for k in range(4):         x = i+row[k]         y = j+col[k]           if x >= 0 and x < r and y >= 0 and y < c and mat[x][y] == 1:             mat[x][y] = 0             stack.append((x, y))   # storing the time at which the patient got infected             time[x][y] = time[i][j]+1       return stack     # function to calculate maximum time def maxTime(hospital):       # array to store the time at which the patients got infected     time = [[0 for i in range(c)] for j in range(r)]   # to store newly infected ones     que = []   # initial run     for i in range(r):         for j in range(c):             if hospital[i][j] == 2:                 que += bfs(i, j, hospital, time)   # iterate till every infected patient has done spreading     while(len(que) != 0):         for x, y in que:             temp = bfs(x, y, hospital, time)         que = temp   # finally calculating maximum time     res = 0     for i in range(r):         for j in range(c):               # checking if there is any uninfected person             if hospital[i][j] == 1:                 return -1             res = max(res, time[i][j])       return res     # Driver Code Starts hospital = [[2, 1, 0, 2, 1],             [1, 0, 1, 2, 1],             [1, 0, 0, 2, 1]]   r = len(hospital) c = len(hospital[0]) print(maxTime(hospital))   # Driver Code Ends

Output

2

Time Complexity: O(N * M)
Auxiliary Space: O(N * M)

Approach 2:This uses the same  BFS traversal technique but instead of using an array of integer to keep track of whether all patients are infected it uses a single integer which reduces overall space consumption and overhead of doing an extra check for uninfected patients.

The basic idea is we will store the count of uninfected persons at the start and as an individual will got infected we will decrement this count. This will remove the overhead of checking  for uninfected persons at the end. And the time at which the last person got  infected will be our final answer.

## C++

 // C++ program for the above approach #include using namespace std;   // Direction arrays vector > direction     = { { 1, 0 }, { 0, -1 }, { -1, 0 }, { 0, 1 } };   // Function to find the maximum time // required for all patients to get infected int maximumTime(vector > arr) {     // Stores the number of rows     int n = arr.size();       // Stores the number of columns     int m = arr[0].size();       // Stores whether particular index(i, j)     // is visited or not      vector> visited(n,vector(m,0));       // Stores index and time of     // infection of infected persons     queue, int> > q;         //Stores uninfected patients count        int uninfected_count=0;             //Stores time at which last person got infected       int time = 0;     // Traverse the matrix     for (int i = 0; i < n; i++) {         for (int j = 0; j < m; j++) {               // If the current patient             // is already infected             if (arr[i][j] == 2) {                   // Push the index of current patient                 // and mark it as visited                 q.push({ { i, j }, 0 });                 visited[i][j] =  1;             }                         //If current patient is uninfected               //increment uninfected count               if(arr[i][j] == 1){                 uninfected_count++;             }         }     }       // Iterate until queue becomes empty     while (!q.empty()) {         // Stores the front element of queue         pair, int> current             = q.front();                     time = current.second;         // Pop out the front element         q.pop();           // Check for all four         // adjacent indices         for (auto it : direction) {               // Find the index of the             // adjacent cell             int i = current.first.first                     + it.first;             int j = current.first.second                     + it.second;               // If the current adjacent             // cell is invalid or it             // contains an infected patient             if (i < 0 || j < 0 || i >= n                 || j >= m || arr[i][j] != 1                 || visited[i][j] != 0) {                   // Continue to the next                 // neighbouring cell                 continue;             }               // Push the infected             // neighbour into queue             q.push({ { i, j }, time + 1 });             visited[i][j] = 1;               uninfected_count--;         }     }       // If an uninfected patient is present     if (uninfected_count != 0)         return -1;         // Return the final result     return time; }   // Driver Code int main() {     vector > arr         = { { 2, 1, 0, 2, 1 },             { 1, 0, 1, 2, 1 },             { 1, 0, 0, 2, 1 } };     cout << maximumTime(arr);       return 0; } // Contributed By Devendra Kolhe

## Java

 // Java program for the above approach import java.util.*;   public class GFG{           static class pair     {         int first, second, third;                    pair(int first,int second,int third)         {              this.first = first;              this.second = second;              this.third = third;         }     }           // Direction arrays     static int direction[][] = { { 1, 0 }, { 0, -1 },                             { -1, 0 }, { 0, 1 } };           // Function to find the maximum time     // required for all patients to get infected     static int maximumTime(int arr[][])     {         // Stores the number of rows         int n = arr.length;               // Stores the number of columns         int m = arr[0].length;               // Stores whether particular index(i, j)         // is visited or not         boolean visited[][] = new boolean[n][m];               // Stores index and time of         // infection of infected persons         Queue q = new LinkedList<>();               //Stores uninfected patients count         int uninfected_count=0;                   //Stores time at which last person got infected         int time = 0;         // Traverse the matrix         for (int i = 0; i < n; i++) {             for (int j = 0; j < m; j++) {                       // If the current patient                 // is already infected                 if (arr[i][j] == 2) {                           // Push the index of current patient                     // and mark it as visited                     q.add( new pair(i, j, 0 ));                     visited[i][j] = true;                 }                               //If current patient is uninfected                 //increment uninfected count                 if(arr[i][j] == 1){                     uninfected_count++;                 }             }         }               // Iterate until queue becomes empty         while (!q.isEmpty()) {             // Stores the front element of queue             pair current = q.peek();                           time = current.third;             // Pop out the front element             q.poll();                   // Check for all four             // adjacent indices             for (int[] it : direction) {                       // Find the index of the                 // adjacent cell                 int i = current.first                         + it[0];                 int j = current.second                         + it[1];                       // If the current adjacent                 // cell is invalid or it                 // contains an infected patient                 if (i < 0 || j < 0 || i >= n                     || j >= m || arr[i][j] != 1                     || visited[i][j]) {                           // Continue to the next                     // neighbouring cell                     continue;                 }                       // Push the infected                 // neighbour into queue                 q.add( new pair( i, j, time + 1 ));                 visited[i][j] = true;                 uninfected_count--;             }         }               // If an uninfected patient is present         if (uninfected_count != 0)             return -1;               // Return the final result         return time;     }           // Driver Code     public static void main(String args[])     {         int arr[][] = { { 2, 1, 0, 2, 1 },                     { 1, 0, 1, 2, 1 },                     { 1, 0, 0, 2, 1 } };                               System.out.println(maximumTime(arr));           } }   // This code is contributed by adityapande88.

Output

2

My Personal Notes arrow_drop_up
Recommended Articles
Page :