给定一个仅由0、1和2组成的矩阵arr [] [] ,分别代表一个空病房,一个未感染的患者和一个已感染的患者。在一个时间单位,被感染的人在索引(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
方法:可以通过在2D矩阵上使用BFS遍历来解决给定的问题。请按照以下步骤解决给定的问题:
- 初始化一个二维数组,将timeofinfection [] []设为-1 ,以便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 persions
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 ininfected 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;
}
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 wether particular index(i, j)
// is visited or not
vector> visited(n,vector(m,0));
// Stores index and time of
// infection of infected persions
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
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 wether particular index(i, j)
// is visited or not
vector> visited(n,vector(m,0));
// Stores index and time of
// infection of infected persions
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
2