鉴于m维的矩阵* n,其中矩阵中的每个单元可具有具有以下含义的值0,1或2:
0: Empty cell
1: Cells have fresh oranges
2: Cells have rotten oranges
因此,任务是确定使所有橙子变烂所需的最短时间是多少。索引为[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
In the first unit of time, all the oranges will be rotten
except the first orange of the last row
which will get rotten in the second unit of time.
Input: arr[][] =
{{2, 1, 0, 2, 1},
{0, 0, 1, 2, 1},
{1, 0, 0, 2, 1}};
Output: -1
方法:这里讨论了基于BFS的方法。
在这篇文章中,我们使用动态编程解决了这个问题。
每个橘子都需要烂掉。任何橙色都可以被最近的橙色烂掉。因此,对于尚未腐烂的每个橙子,我们找到其与腐烂的橙子的最小距离,然后取最大的最大值,这表示腐烂所有橙子所需的最短时间。
令dp(i,j)=该橙与任何烂橙的最小距离,因此,DP状态为:
dp(i, j) = 0 if arr[i][j] == 2
dp(i, j) = INT_MAX if arr[i][j] == 0
if dp(i, j) >0 and dp(i, j)
dp(i – 1, j), dp(i, j + 1), dp(i, j – 1)))
else dp(i, j) = 1 + min(dp(i + 1, j), dp(i – 1, j), dp(i, j + 1), dp(i, j – 1))
对于所有i,j,我们的答案将是max(dp(i,j)),其中arr [i] [j] == 1。
下面是上述方法的实现:
C++
// C++ implementation of the approach
#include
using namespace std;
#define C 5
#define R 3
#define INT_MAX 10000000
// DP table to memoize the values
int table[R][C] = { 0 };
// Visited array to keep
// track of visited nodes
// in order to avoid infinite loops
int visited[R][C] = { 0 };
// Function to return the
// minimum of four numbers
int min(int p, int q, int r, int s)
{
int temp1 = p < q ? p : q;
int temp2 = r < s ? r : s;
if (temp1 < temp2)
return temp1;
return temp2;
}
// Function to return the minimum distance
// to any rotten orange from [i, j]
int Distance(int arr[R][C], int i, int j)
{
// If i, j lie outside the array
if (i >= R || j >= C || i < 0 || j < 0)
return INT_MAX;
// If 0 then it can't lead to
// any path so return INT_MAX
else if (arr[i][j] == 0) {
table[i][j] = INT_MAX;
return INT_MAX;
}
// If 2 then we have reached
// our rotten oranges
// so return from here
else if (arr[i][j] == 2) {
table[i][j] = 0;
return 0;
}
// If this node is already visited
// then return to avoid infinite loops
else if (visited[i][j]) {
return INT_MAX;
}
else {
// Mark the current node as visited
visited[i][j] = 1;
// Check in all four possible directions
int temp1 = Distance(arr, i + 1, j);
int temp2 = Distance(arr, i - 1, j);
int temp3 = Distance(arr, i, j + 1);
int temp4 = Distance(arr, i, j - 1);
// Take the minimum of all
int min_value = 1 + min(temp1,
temp2, temp3, temp4);
// If result already exists in the table
// check if min_value is less
// than existing value
if (table[i][j] > 0 &&
table[i][j] < INT_MAX) {
if (min_value < table[i][j])
table[i][j] = min_value;
}
else
table[i][j] = min_value;
visited[i][j] = 0;
return table[i][j];
}
}
// Function to return the minimum time
// required to rot all the oranges
int minTime(int arr[][C])
{
int max = 0;
// Calculate the minimum
// distances to any rotten
// orange from all the fresh oranges
for (int i = 0; i < R; i++) {
for (int j = 0; j < C; j++) {
if (arr[i][j] == 1)
Distance(arr, i, j);
}
}
// Pick the maximum distance of fresh orange
// to some rotten orange
for (int i = 0; i < R; i++) {
for (int j = 0; j < C; j++) {
if (arr[i][j] == 1 &&
table[i][j] > max)
max = table[i][j];
}
}
// If all oranges can be rotten
if (max < INT_MAX)
return max;
return -1;
}
// Driver Code
int main()
{
int arr[R][C] = { { 2, 1, 0, 2, 1 },
{ 0, 0, 1, 2, 1 },
{ 1, 0, 0, 2, 1 } };
cout << minTime(arr);
return 0;
}
Java
// Java implementation of the approach
class GFG {
static int C = 5;
static int R = 3;
static int INT_MAX = 10000000;
// DP table to memoize the values
static int[][] table = new int[R][C];
// Visited array to keep
// track of visited nodes
// in order to avoid infinite loops
static int[][] visited = new int[R][C];
// Function to return the
// minimum of four numbers
static int min(int p, int q, int r, int s)
{
int temp1 = p < q ? p : q;
int temp2 = r < s ? r : s;
if (temp1 < temp2)
return temp1;
return temp2;
}
// Function to return the
// minimum distance
// to any rotten orange from [i, j]
static int Distance(int arr[][], int i, int j)
{
// If i, j lie outside the array
if (i >= R || j >= C || i < 0 || j < 0)
return INT_MAX;
// If 0 then it can't lead to
// any path so return INT_MAX
else if (arr[i][j] == 0) {
table[i][j] = INT_MAX;
return INT_MAX;
}
// If 2 then we have reached
// our rotten oranges
// so return from here
else if (arr[i][j] == 2) {
table[i][j] = 0;
return 0;
}
// If this node is already visited
// then return to avoid
// infinite loops
else if (visited[i][j] == 1) {
return INT_MAX;
}
else {
// Mark the current node
// as visited
visited[i][j] = 1;
// Check in all four
// possible directions
int temp1 = Distance(arr, i + 1, j);
int temp2 = Distance(arr, i - 1, j);
int temp3 = Distance(arr, i, j + 1);
int temp4 = Distance(arr, i, j - 1);
// Take the minimum of all
int min_value
= 1 + min(temp1, temp2, temp3, temp4);
// If result already exists in
// the table check if min_value
// is less than existing value
if (table[i][j] > 0 &&
table[i][j] < INT_MAX) {
if (min_value < table[i][j])
table[i][j] = min_value;
}
else
table[i][j] = min_value;
visited[i][j] = 0;
}
return table[i][j];
}
// Function to return the minimum time
// required to rot all the oranges
static int minTime(int arr[][])
{
int max = 0;
// Calculate the minimum
// distances to any rotten
// orange from all the fresh oranges
for (int i = 0; i < R; i++) {
for (int j = 0; j < C; j++) {
if (arr[i][j] == 1)
Distance(arr, i, j);
}
}
// Pick the maximum distance
// of fresh orange
// to some rotten orange
for (int i = 0; i < R; i++) {
for (int j = 0; j < C; j++) {
if (arr[i][j] == 1 &&
table[i][j] > max)
max = table[i][j];
}
}
// If all oranges can be rotten
if (max < INT_MAX)
return max;
return -1;
}
// Driver Code
public static void main(String[] args)
{
int arr[][] = { { 2, 1, 0, 2, 1 },
{ 0, 0, 1, 2, 1 },
{ 1, 0, 0, 2, 1 } };
System.out.println(minTime(arr));
}
}
// This code is contributed by Rajput-Ji
Python3
# Python 3 implementation of the approach
C = 5
R = 3
INT_MAX = 10000000
# DP table to memoize the values
table = [[0 for i in range(C)]
for j in range(R)]
# Visited array to keep track
# of visited nodes
# in order to avoid infinite loops
visited = [[0 for i in range(C)]
for j in range(R)]
# Function to return the
# minimum of four numbers
def min(p, q, r, s):
if(p < q):
temp1 = p
else:
temp1 = q
if(r < s):
temp2 = r
else:
temp2 = s
if (temp1 < temp2):
return temp1
return temp2
# Function to return the
# minimum distance
# to any rotten orange from [i, j]
def Distance(arr, i, j):
# If i, j lie outside the array
if (i >= R or j >= C or
i < 0 or j < 0):
return INT_MAX
# If 0 then it can't lead to
# any path so return INT_MAX
elif (arr[i][j] == 0):
table[i][j] = INT_MAX
return INT_MAX
# If 2 then we have reached
# our rotten oranges
# so return from here
elif (arr[i][j] == 2):
table[i][j] = 0
return 0
# If this node is already visited
# then return to avoid infinite loops
elif (visited[i][j]):
return INT_MAX
else:
# Mark the current node as visited
visited[i][j] = 1
# Check in all four
# possible directions
temp1 = Distance(arr, i + 1, j)
temp2 = Distance(arr, i - 1, j)
temp3 = Distance(arr, i, j + 1)
temp4 = Distance(arr, i, j - 1)
# Take the minimum of all
min_value = 1 + min(temp1, temp2,
temp3, temp4)
if table[i][j] > 0 and \
table[i][j] < INT_MAX:
if min_value < table[i][j]:
table[i][j] = min_value
else:
table[i][j] = min_value
visited[i][j] = 0
return table[i][j]
# Function to return the minimum time
# required to rot all the oranges
def minTime(arr):
max = 0
# Calculate the minimum distances
# to any rotten
# orange from all the fresh oranges
for i in range(R):
for j in range(C):
if (arr[i][j] == 1):
Distance(arr, i, j)
# Pick the maximum distance
# of fresh orange
# to some rotten orange
for i in range(R):
for j in range(C):
if (arr[i][j] == 1 and
table[i][j] > max):
max = table[i][j]
# If all oranges can be rotten
if (max < INT_MAX):
return max
return -1
# Driver Code
if __name__ == '__main__':
arr = [[2, 1, 0, 2, 1],
[0, 0, 1, 2, 1],
[1, 0, 0, 2, 1]]
print(minTime(arr))
C#
// C# implementation of
// the above approach
using System;
class GFG{
static int C = 5;
static int R = 3;
static int INT_MAX =
10000000;
// DP table to memoize
// the values
static int[,] table =
new int[R, C];
// Visited array to keep
// track of visited nodes
// in order to avoid infinite
// loops
static int[,] visited =
new int[R, C];
// Function to return the
// minimum of four numbers
static int min(int p, int q,
int r, int s)
{
int temp1 = p < q ? p : q;
int temp2 = r < s ? r : s;
if (temp1 < temp2)
return temp1;
return temp2;
}
// Function to return the
// minimum distance
// to any rotten orange
// from [i, j]
static int Distance(int [,]arr,
int i, int j)
{
// If i, j lie outside
// the array
if (i >= R || j >= C ||
i < 0 || j < 0)
return INT_MAX;
// If 0 then it can't lead
// to any path so return
// INT_MAX
else if (arr[i, j] == 0)
{
table[i, j] = INT_MAX;
return INT_MAX;
}
// If 2 then we have reached
// our rotten oranges
// so return from here
else if (arr[i, j] == 2)
{
table[i, j] = 0;
return 0;
}
// If this node is already
// visited then return to
// avoid infinite loops
else if (visited[i, j] == 1)
{
return INT_MAX;
}
else
{
// Mark the current node
// as visited
visited[i, j] = 1;
// Check in all four
// possible directions
int temp1 = Distance(arr,
i + 1, j);
int temp2 = Distance(arr,
i - 1, j);
int temp3 = Distance(arr,
i, j + 1);
int temp4 = Distance(arr,
i, j - 1);
// Take the minimum of all
int min_value = 1 + min(temp1, temp2,
temp3, temp4);
// If result already exists in
// the table check if min_value
// is less than existing value
if (table[i, j] > 0 &&
table[i, j] < INT_MAX)
{
if (min_value < table[i, j])
table[i, j] = min_value;
}
else
table[i, j] = min_value;
visited[i, j] = 0;
}
return table[i, j];
}
// Function to return the minimum
// time required to rot all the
// oranges
static int minTime(int [,]arr)
{
int max = 0;
// Calculate the minimum
// distances to any rotten
// orange from all the fresh
// oranges
for (int i = 0; i < R; i++)
{
for (int j = 0; j < C; j++)
{
if (arr[i, j] == 1)
Distance(arr, i, j);
}
}
// Pick the maximum distance
// of fresh orange
// to some rotten orange
for (int i = 0; i < R; i++)
{
for (int j = 0; j < C; j++)
{
if (arr[i, j] == 1 &&
table[i, j] > max)
max = table[i, j];
}
}
// If all oranges can be
// rotten
if (max < INT_MAX)
return max;
return -1;
}
// Driver Code
public static void Main(string[] args)
{
int [,]arr = {{2, 1, 0, 2, 1},
{0, 0, 1, 2, 1},
{1, 0, 0, 2, 1}};
Console.Write(minTime(arr));
}
}
// This code is contributed by Chitranayal
-1