Minimum time required to rot all oranges | Dynamic Programming
Last Updated :
26 Dec, 2022
Given a matrix of dimension m * n where each cell in the matrix can have values 0, 1, or 2 which has the following meaning:
0: Empty cell
1: Cells have fresh oranges
2: Cells have rotten oranges
So the task is to determine what is the minimum time required so that all the oranges become rotten. A rotten orange at index [i, j] can rot other fresh oranges at indexes [i – 1, j], [i + 1, j], [i, j – 1], [i, j + 1] (up, down, left and right). If it is impossible to rot every orange then simply return -1.
Examples:
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
Approach: A BFS-based approach has been discussed here.
In this post, we solve the problem using Dynamic Programming.
Every orange needs to be rotten. Any orange can be rotten by its nearest rotten orange. So, for every orange which is not rotten yet, we find its minimum distance from rotten orange, Then we take the maximum of all which will represent the minimum time required to rot all oranges.
Let dp(i, j) = Minimum Distance of this orange from any rotten orange So, the DP states will be:
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)<INT_MAX
then dp(i, j) = min(dp(i, j) , 1 + min(dp(i + 1, 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))
And our answer will be max(dp(i, j)) for all i, j where arr[i][j] == 1.
Below is the implementation of the above approach:
C++
#include <iostream>
using namespace std;
#define C 5
#define R 3
#define INT_MAX 10000000
int table[R][C] = { 0 };
int visited[R][C] = { 0 };
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;
}
int Distance( int arr[R][C], int i, int j)
{
if (i >= R || j >= C || i < 0 || j < 0)
return INT_MAX;
else if (arr[i][j] == 0) {
table[i][j] = INT_MAX;
return INT_MAX;
}
else if (arr[i][j] == 2) {
table[i][j] = 0;
return 0;
}
else if (visited[i][j]) {
return INT_MAX;
}
else {
visited[i][j] = 1;
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);
int min_value = 1 + min(temp1,
temp2, temp3, temp4);
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];
}
}
int minTime( int arr[][C])
{
int max = 0;
for ( int i = 0; i < R; i++) {
for ( int j = 0; j < C; j++) {
if (arr[i][j] == 1)
Distance(arr, i, j);
}
}
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 (max < INT_MAX)
return max;
return -1;
}
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
class GFG {
static int C = 5 ;
static int R = 3 ;
static int INT_MAX = 10000000 ;
static int [][] table = new int [R][C];
static int [][] visited = new int [R][C];
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;
}
static int Distance( int arr[][], int i, int j)
{
if (i >= R || j >= C || i < 0 || j < 0 )
return INT_MAX;
else if (arr[i][j] == 0 ) {
table[i][j] = INT_MAX;
return INT_MAX;
}
else if (arr[i][j] == 2 ) {
table[i][j] = 0 ;
return 0 ;
}
else if (visited[i][j] == 1 ) {
return INT_MAX;
}
else {
visited[i][j] = 1 ;
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 );
int min_value
= 1 + min(temp1, temp2, temp3, temp4);
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];
}
static int minTime( int arr[][])
{
int max = 0 ;
for ( int i = 0 ; i < R; i++) {
for ( int j = 0 ; j < C; j++) {
if (arr[i][j] == 1 )
Distance(arr, i, j);
}
}
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 (max < INT_MAX)
return max;
return - 1 ;
}
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));
}
}
|
Python3
C = 5
R = 3
INT_MAX = 10000000
table = [[ 0 for i in range (C)]
for j in range (R)]
visited = [[ 0 for i in range (C)]
for j in range (R)]
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
def Distance(arr, i, j):
if (i > = R or j > = C or
i < 0 or j < 0 ):
return INT_MAX
elif (arr[i][j] = = 0 ):
table[i][j] = INT_MAX
return INT_MAX
elif (arr[i][j] = = 2 ):
table[i][j] = 0
return 0
elif (visited[i][j]):
return INT_MAX
else :
visited[i][j] = 1
temp1 = Distance(arr, i + 1 , j)
temp2 = Distance(arr, i - 1 , j)
temp3 = Distance(arr, i, j + 1 )
temp4 = Distance(arr, i, j - 1 )
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]
def minTime(arr):
max = 0
for i in range (R):
for j in range (C):
if (arr[i][j] = = 1 ):
Distance(arr, i, j)
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 ( max < INT_MAX):
return max
return - 1
if __name__ = = '__main__' :
arr = [[ 2 , 1 , 0 , 2 , 1 ],
[ 0 , 0 , 1 , 2 , 1 ],
[ 1 , 0 , 0 , 2 , 1 ]]
print (minTime(arr))
|
C#
using System;
class GFG{
static int C = 5;
static int R = 3;
static int INT_MAX =
10000000;
static int [,] table =
new int [R, C];
static int [,] visited =
new int [R, C];
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;
}
static int Distance( int [,]arr,
int i, int j)
{
if (i >= R || j >= C ||
i < 0 || j < 0)
return INT_MAX;
else if (arr[i, j] == 0)
{
table[i, j] = INT_MAX;
return INT_MAX;
}
else if (arr[i, j] == 2)
{
table[i, j] = 0;
return 0;
}
else if (visited[i, j] == 1)
{
return INT_MAX;
}
else
{
visited[i, j] = 1;
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);
int min_value = 1 + min(temp1, temp2,
temp3, temp4);
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];
}
static int minTime( int [,]arr)
{
int max = 0;
for ( int i = 0; i < R; i++)
{
for ( int j = 0; j < C; j++)
{
if (arr[i, j] == 1)
Distance(arr, i, j);
}
}
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 (max < INT_MAX)
return max;
return -1;
}
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));
}
}
|
Javascript
<script>
let C = 5;
let R = 3;
let INT_MAX = 10000000;
let table = new Array(R);
let visited = new Array(R);
for (let i = 0; i < R; i++)
{
table[i] = new Array(C);
visited[i] = new Array(C);
}
function min(p, q, r, s)
{
let temp1 = p < q ? p : q;
let temp2 = r < s ? r : s;
if (temp1 < temp2)
return temp1;
return temp2;
}
function Distance(arr, i, j)
{
if (i >= R || j >= C || i < 0 || j < 0)
return INT_MAX;
else if (arr[i][j] == 0) {
table[i][j] = INT_MAX;
return INT_MAX;
}
else if (arr[i][j] == 2) {
table[i][j] = 0;
return 0;
}
else if (visited[i][j] == 1) {
return INT_MAX;
}
else {
visited[i][j] = 1;
let temp1 = Distance(arr, i + 1, j);
let temp2 = Distance(arr, i - 1, j);
let temp3 = Distance(arr, i, j + 1);
let temp4 = Distance(arr, i, j - 1);
let min_value
= 1 + min(temp1, temp2, temp3, temp4);
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 minTime(arr)
{
let max = 0;
for (let i = 0; i < R; i++) {
for (let j = 0; j < C; j++) {
if (arr[i][j] == 1)
Distance(arr, i, j);
}
}
for (let i = 0; i < R; i++) {
for (let j = 0; j < C; j++) {
if (arr[i][j] == 1 &&
table[i][j] > max)
max = table[i][j];
}
}
if (max < INT_MAX)
return max;
return -1;
}
let arr = [[ 2, 1, 0, 2, 1],[0, 0, 1, 2, 1 ],[1, 0, 0, 2, 1]]
document.write(minTime(arr));
</script>
|
Time Complexity: O(R*C), where R and C are the number of rows and columns of the given arr[][]
Auxiliary Space: O(R*C)
Share your thoughts in the comments
Please Login to comment...