# 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

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.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`

## Javascript

 ``

## 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.size();` `    ``// Stores whether particular index(i, j)``    ``// is visited or not ``    ``vector> visited(n,vector<``bool``>(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