Related Articles

# Minimum time required to rot all oranges | Dynamic Programming

• Difficulty Level : Hard
• Last Updated : 02 Jun, 2021

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:
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++

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

## Javascript

 ``
Output
`-1`

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.

My Personal Notes arrow_drop_up