给定一个矩阵arr[][] ,仅由 0、1 和 2 组成,分别表示空病房、未感染患者和感染患者。在一个时间单位,被感染的人在索引(i,j)的可感染邻近它即未感染的人,在索引(i – 1,j)中,第(i + 1,j)的(I,J – 1 )和(i, j + 1) 。任务是找到感染所有患者所需的最短时间。如果不可能感染所有患者,则打印“-1” 。
例子:
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
方法:给定的问题可以通过在二维矩阵上使用 BFS 遍历来解决。请按照以下步骤解决给定的问题:
- 用-1初始化一个二维数组,比如timeofinfection[][] ,这样timeofinfection[i][j]存储索引(i, j)处的患者被感染的时间。
- 初始化队列以存储受感染患者的索引及其感染时间。
- 遍历给定矩阵arr[][]并执行以下操作:
- 如果单元格(i, j) 处的值为2 ,则将该单元格推入队列,感染时间为0,即{i, j, 0} 。
- 迭代直到队列非空并执行以下步骤:
- 弹出队列的前端元素并将其存储在一个变量中,比如current 。
- 从当前弹出的单元格(i, j) 开始,如果相邻单元格有未访问的感染者,则将具有(1 + 当前弹出单元格的感染时间)的相邻单元格的索引推入队列。
- 完成上述步骤后,如果访问了所有感染者,即所有感染者的感染时间为非负,则打印矩阵timeofinfection[][]中存在的最大元素作为所需的最大时间单位感染所有患者。
- 否则,打印“-1” 。
下面是上述方法的实现:
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
Javascript
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.
2
时间复杂度: O(N * M)
辅助空间: O(N * M)
方法 2 :这使用相同的 BFS 遍历技术,但不是使用整数数组来跟踪是否所有患者都被感染,而是使用单个整数,这减少了整体空间消耗和对未感染患者进行额外检查的开销。
基本思想是我们将在开始时存储未感染者的数量,并且当一个人被感染时,我们将减少这个数量。这将消除最后检查未感染者的开销。最后一个人被感染的时间将是我们的最终答案。
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.
2
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。