Minimum time required to rot all oranges - GeeksforGeeks

28 Feb, 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
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 orange 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[][C] = { {2, 1, 0, 2, 1},
                     {1, 0, 1, 2, 1},
                     {1, 0, 0, 2, 1}};
Output:
All oranges can become rotten in 2-time frames.
Explanation: 
At 0th time frame:
 {2, 1, 0, 2, 1}
 {1, 0, 1, 2, 1}
 {1, 0, 0, 2, 1}

At 1st time frame:
 {2, 2, 0, 2, 2}
 {2, 0, 2, 2, 2}
 {1, 0, 0, 2, 2}

At 2nd time frame:
 {2, 2, 0, 2, 2}
 {2, 0, 2, 2, 2}
 {2, 0, 0, 2, 2}


Input:  arr[][C] = { {2, 1, 0, 2, 1},
                     {0, 0, 1, 2, 1},
                     {1, 0, 0, 2, 1}};
Output:
All oranges cannot be rotten.
Explanation: 
At 0th time frame:
{2, 1, 0, 2, 1}
{0, 0, 1, 2, 1}
{1, 0, 0, 2, 1}

At 1st time frame:
{2, 2, 0, 2, 2}
{0, 0, 2, 2, 2}
{1, 0, 0, 2, 2}

At 2nd time frame:
{2, 2, 0, 2, 2}
{0, 0, 2, 2, 2}
{1, 0, 0, 2, 2}
...
The 1 at the bottom left corner of the matrix is never rotten.
Naive Solution:  
Approach: The idea is very basic. Traverse through all oranges in multiple rounds. In every round, rot the oranges to the adjacent position of oranges which were rotten in the last round.
Algorithm: Create a variable no = 2 and changed = falseRun a loop until there is no cell of the matrix which is changed in an iteration.Run a nested loop and traverse the matrix. If the element of the matrix is equal to no then assign the adjacent elements to no + 1 if the adjacent element’s value is equal to 1, i.e. not rotten, and update changed to true.Traverse the matrix and check if there is any cell which is 1. If 1 is present return -1Else return no – 2
Create a variable no = 2 and changed = falseRun a loop until there is no cell of the matrix which is changed in an iteration.Run a nested loop and traverse the matrix. If the element of the matrix is equal to no then assign the adjacent elements to no + 1 if the adjacent element’s value is equal to 1, i.e. not rotten, and update changed to true.Traverse the matrix and check if there is any cell which is 1. If 1 is present return -1Else return no – 2
Create a variable no = 2 and changed = false
Run a loop until there is no cell of the matrix which is changed in an iteration.
Run a nested loop and traverse the matrix. If the element of the matrix is equal to no then assign the adjacent elements to no + 1 if the adjacent element’s value is equal to 1, i.e. not rotten, and update changed to true.
Traverse the matrix and check if there is any cell which is 1. If 1 is present return -1
Else return no – 2
Implementation:
C++14
Java
Python3
C#
Javascript
// C++ program to rot all oranges when u can move// in all the four direction from a rotten orange#include <bits/stdc++.h>using namespace std; const int R = 3;const int C = 5; // Check if i, j is under the array limits of row and columnbool issafe(int i, int j){    if (i >= 0 && i < R && j >= 0 && j < C)        return true;    return false;} int rotOranges(int v[R][C]){    bool changed = false;    int no = 2;    while (true) {        for (int i = 0; i < R; i++) {            for (int j = 0; j < C; j++) {                 // Rot all other oranges present at                // (i+1, j), (i, j-1), (i, j+1), (i-1, j)                if (v[i][j] == no) {                    if (issafe(i + 1, j) && v[i + 1][j] == 1) {                        v[i + 1][j] = v[i][j] + 1;                        changed = true;                    }                    if (issafe(i, j + 1) && v[i][j + 1] == 1) {                        v[i][j + 1] = v[i][j] + 1;                        changed = true;                    }                    if (issafe(i - 1, j) && v[i - 1][j] == 1) {                        v[i - 1][j] = v[i][j] + 1;                        changed = true;                    }                    if (issafe(i, j - 1) && v[i][j - 1] == 1) {                        v[i][j - 1] = v[i][j] + 1;                        changed = true;                    }                }            }        }         // if no rotten orange found it means all        // oranges rottened now        if (!changed)            break;        changed = false;        no++;    }     for (int i = 0; i < R; i++) {        for (int j = 0; j < C; j++) {             // if any orange is found to be            // not rotten then ans is not possible            if (v[i][j] == 1)                return -1;        }    }     // Because initial value for a rotten    // orange was 2    return no - 2;} // Driver functionint main(){     int v[R][C] = { { 2, 1, 0, 2, 1 },                    { 1, 0, 1, 2, 1 },                    { 1, 0, 0, 2, 1 } };     cout << "Max time incurred: " << rotOranges(v);     return 0;}
// Java program to rot all oranges when u can move// in all the four direction from a rotten orangeclass GFG{     static int R = 3;static int C = 5;  // Check if i, j is under the array// limits of row and columnstatic boolean issafe(int i, int j){    if (i >= 0 && i < R &&        j >= 0 && j < C)        return true;             return false;}  static int rotOranges(int v[][]){    boolean changed = false;    int no = 2;         while (true)    {        for(int i = 0; i < R; i++)        {            for(int j = 0; j < C; j++)            {                                 // Rot all other oranges present at                // (i+1, j), (i, j-1), (i, j+1), (i-1, j)                if (v[i][j] == no)                {                    if (issafe(i + 1, j) &&                             v[i + 1][j] == 1)                    {                        v[i + 1][j] = v[i][j] + 1;                        changed = true;                    }                    if (issafe(i, j + 1) &&                             v[i][j + 1] == 1)                    {                        v[i][j + 1] = v[i][j] + 1;                        changed = true;                    }                    if (issafe(i - 1, j) &&                             v[i - 1][j] == 1)                    {                        v[i - 1][j] = v[i][j] + 1;                        changed = true;                    }                    if (issafe(i, j - 1) &&                             v[i][j - 1] == 1)                    {                        v[i][j - 1] = v[i][j] + 1;                        changed = true;                    }                }            }        }          // If no rotten orange found it means all        // oranges rottened now        if (!changed)            break;                     changed = false;        no++;    }      for(int i = 0; i < R; i++)    {        for(int j = 0; j < C; j++)        {                         // If any orange is found to be            // not rotten then ans is not possible            if (v[i][j] == 1)                return -1;        }    }      // Because initial value for a rotten    // orange was 2    return no - 2;} // Driver Codepublic static void main(String[] args){    int v[][] = { { 2, 1, 0, 2, 1 },                  { 1, 0, 1, 2, 1 },                  { 1, 0, 0, 2, 1 } };      System.out.println("Max time incurred: " +                       rotOranges(v));}} // This code is contributed by divyesh072019
# Python3 program to rot all# oranges when u can move# in all the four direction# from a rotten orangeR = 3C = 5 # Check if i, j is under the# array limits of row and# columndef issafe(i, j):     if (i >= 0 and i < R and        j >= 0 and j < C):        return True    return False def rotOranges(v):     changed = False    no = 2    while (True):        for i in range(R):            for j in range(C):                 # Rot all other oranges                # present at (i+1, j),                # (i, j-1), (i, j+1),                # (i-1, j)                if (v[i][j] == no):                    if (issafe(i + 1, j) and                        v[i + 1][j] == 1):                        v[i + 1][j] = v[i][j] + 1                        changed = True                     if (issafe(i, j + 1) and                        v[i][j + 1] == 1):                        v[i][j + 1] = v[i][j] + 1                        changed = True                     if (issafe(i - 1, j) and                        v[i - 1][j] == 1):                        v[i - 1][j] = v[i][j] + 1                        changed = True                     if (issafe(i, j - 1) and                        v[i][j - 1] == 1):                        v[i][j - 1] = v[i][j] + 1                        changed = True         # if no rotten orange found        # it means all oranges rottened        # now        if (not changed):           break        changed = False        no += 1     for i in range(R):        for j in range(C):             # if any orange is found            # to be not rotten then            # ans is not possible            if (v[i][j] == 1):                return -1     # Because initial value    # for a rotten orange was 2    return no - 2 # Driver functionif __name__ == "__main__":     v = [[2, 1, 0, 2, 1],         [1, 0, 1, 2, 1],         [1, 0, 0, 2, 1]]     print("Max time incurred: ",           rotOranges(v)) # This code is contributed by Chitranayal
// C# program to rot all oranges when u can move// in all the four direction from a rotten orangeusing System;class GFG {         static int R = 3;    static int C = 5;          // Check if i, j is under the array   // limits of row and column    static bool issafe(int i, int j)    {        if (i >= 0 && i < R && j >= 0 && j < C)            return true;        return false;    }          static int rotOranges(int[,] v)    {        bool changed = false;        int no = 2;        while (true) {            for (int i = 0; i < R; i++) {                for (int j = 0; j < C; j++) {                          // Rot all other oranges present at                    // (i+1, j), (i, j-1), (i, j+1), (i-1, j)                    if (v[i, j] == no) {                        if (issafe(i + 1, j) && v[i + 1, j] == 1) {                            v[i + 1, j] = v[i, j] + 1;                            changed = true;                        }                        if (issafe(i, j + 1) && v[i, j + 1] == 1) {                            v[i, j + 1] = v[i, j] + 1;                            changed = true;                        }                        if (issafe(i - 1, j) && v[i - 1, j] == 1) {                            v[i - 1, j] = v[i, j] + 1;                            changed = true;                        }                        if (issafe(i, j - 1) && v[i, j - 1] == 1) {                            v[i, j - 1] = v[i, j] + 1;                            changed = true;                        }                    }                }            }                  // if no rotten orange found it means all            // oranges rottened now            if (!changed)                break;            changed = false;            no++;        }              for (int i = 0; i < R; i++) {            for (int j = 0; j < C; j++) {                      // if any orange is found to be                // not rotten then ans is not possible                if (v[i, j] == 1)                    return -1;            }        }              // Because initial value for a rotten        // orange was 2        return no - 2;    }   static void Main() {           int[ , ] v = { { 2, 1, 0, 2, 1 },                { 1, 0, 1, 2, 1 },                { 1, 0, 0, 2, 1 } };      Console.Write("Max time incurred: " + rotOranges(v));  }} // This code is contributed by divyeshrabadiya07
<script>    // Javascript program to rot all oranges when u can move    // in all the four direction from a rotten orange    let R = 3;    let C = 5;     // Check if i, j is under the array limits of row and column    function issafe(i, j)    {        if (i >= 0 && i < R && j >= 0 && j < C)            return true;        return false;    }     function rotOranges(v)    {        let changed = false;        let no = 2;        while (true) {            for (let i = 0; i < R; i++) {                for (let j = 0; j < C; j++) {                     // Rot all other oranges present at                    // (i+1, j), (i, j-1), (i, j+1), (i-1, j)                    if (v[i][j] == no) {                        if (issafe(i + 1, j) && v[i + 1][j] == 1) {                            v[i + 1][j] = v[i][j] + 1;                            changed = true;                        }                        if (issafe(i, j + 1) && v[i][j + 1] == 1) {                            v[i][j + 1] = v[i][j] + 1;                            changed = true;                        }                        if (issafe(i - 1, j) && v[i - 1][j] == 1) {                            v[i - 1][j] = v[i][j] + 1;                            changed = true;                        }                        if (issafe(i, j - 1) && v[i][j - 1] == 1) {                            v[i][j - 1] = v[i][j] + 1;                            changed = true;                        }                    }                }            }             // if no rotten orange found it means all            // oranges rottened now            if (!changed)                break;            changed = false;            no++;        }         for (let i = 0; i < R; i++) {            for (let j = 0; j < C; j++) {                 // if any orange is found to be                // not rotten then ans is not possible                if (v[i][j] == 1)                    return -1;            }        }         // Because initial value for a rotten        // orange was 2        return no - 2;    } // Driver code    let v = [ [ 2, 1, 0, 2, 1 ],                    [ 1, 0, 1, 2, 1 ],                    [ 1, 0, 0, 2, 1 ] ];      document.write("Max time incurred: " + rotOranges(v));         // This code is contributed by mukesh07.</script>
Max time incurred: 2
 
Complexity Analysis: Time Complexity : O((R*C) * (R *C)). The matrix needs to be traversed again and again until there is no change in the matrix, that can happen max(R *C)/2 times. So time complexity is O((R * C) * (R *C)).Space Complexity:O(1). No extra space is required.
Time Complexity : O((R*C) * (R *C)). The matrix needs to be traversed again and again until there is no change in the matrix, that can happen max(R *C)/2 times. So time complexity is O((R * C) * (R *C)).
Space Complexity:O(1). No extra space is required.
Efficient Solution 
Approach: The idea is to use Breadth First Search. The condition of oranges getting rotten is when they come in contact with other rotten oranges. This is similar to breadth-first search where the graph is divided into layers or circles and the search is done from lower or closer layers to deeper or higher layers. In the previous approach, the idea was based on BFS but the implementation was poor and inefficient. To find the elements whose values are no the whole matrix had to be traversed. So that time can be reduced by using this efficient approach of BFS.  
Algorithm: Create an empty queue Q. Find all rotten oranges and enqueue them to Q. Also, enqueue a delimiter to indicate the beginning of the next time frame.Run a loop While Q is not emptyDo following while delimiter in Q is not reachedDequeue an orange from the queue, rot all adjacent oranges. While rotting the adjacent, make sure that the time frame is incremented only once. And the time frame is not incremented if there are no adjacent oranges.Dequeue the old delimiter and enqueue a new delimiter. The oranges rotten in the previous time frame lie between the two delimiters.
Create an empty queue Q. Find all rotten oranges and enqueue them to Q. Also, enqueue a delimiter to indicate the beginning of the next time frame.Run a loop While Q is not emptyDo following while delimiter in Q is not reachedDequeue an orange from the queue, rot all adjacent oranges. While rotting the adjacent, make sure that the time frame is incremented only once. And the time frame is not incremented if there are no adjacent oranges.Dequeue the old delimiter and enqueue a new delimiter. The oranges rotten in the previous time frame lie between the two delimiters.
Create an empty queue Q. Find all rotten oranges and enqueue them to Q. Also, enqueue a delimiter to indicate the beginning of the next time frame.Run a loop While Q is not emptyDo following while delimiter in Q is not reached
Find all rotten oranges and enqueue them to Q. Also, enqueue a delimiter to indicate the beginning of the next time frame.Run a loop While Q is not emptyDo following while delimiter in Q is not reached
Find all rotten oranges and enqueue them to Q. Also, enqueue a delimiter to indicate the beginning of the next time frame.
Run a loop While Q is not empty
Do following while delimiter in Q is not reached
Dequeue an orange from the queue, rot all adjacent oranges. While rotting the adjacent, make sure that the time frame is incremented only once. And the time frame is not incremented if there are no adjacent oranges.
Dequeue the old delimiter and enqueue a new delimiter. The oranges rotten in the previous time frame lie between the two delimiters.
Dry run of the above approach:
Implementation:
C++
Java
Python3
C#
// C++ program to find minimum time required to make all// oranges rotten#include<bits/stdc++.h>#define R 3#define C 5using namespace std; // function to check whether a cell is valid / invalidbool isvalid(int i, int j){    return (i >= 0 && j >= 0 && i < R && j < C);} // structure for storing coordinates of the cellstruct ele {    int x, y;}; // Function to check whether the cell is delimiter// which is (-1, -1)bool isdelim(ele temp){    return (temp.x == -1 && temp.y == -1);} // Function to check whether there is still a fresh// orange remainingbool checkall(int arr[][C]){    for (int i=0; i<R; i++)       for (int j=0; j<C; j++)          if (arr[i][j] == 1)             return true;    return false;} // This function finds if it is possible to rot all oranges or not.// If possible, then it returns minimum time required to rot all,// otherwise returns -1int rotOranges(int arr[][C]){    // Create a queue of cells    queue<ele> Q;    ele temp;    int ans = 0;     // Store all the cells having rotten orange in first time frame    for (int i=0; i<R; i++)    {       for (int j=0; j<C; j++)       {            if (arr[i][j] == 2)            {                temp.x = i;                temp.y = j;                Q.push(temp);            }        }    }     // Separate these rotten oranges from the oranges which will rotten    // due the oranges in first time frame using delimiter which is (-1, -1)    temp.x = -1;    temp.y = -1;    Q.push(temp);     // Process the grid while there are rotten oranges in the Queue    while (!Q.empty())    {        // This flag is used to determine whether even a single fresh        // orange gets rotten due to rotten oranges in current time        // frame so we can increase the count of the required time.        bool flag = false;         // Process all the rotten oranges in current time frame.        while (!isdelim(Q.front()))        {            temp = Q.front();             // Check right adjacent cell that if it can be rotten            if (isvalid(temp.x+1, temp.y) && arr[temp.x+1][temp.y] == 1)            {                // if this is the first orange to get rotten, increase                // count and set the flag.                if (!flag) ans++, flag = true;                 // Make the orange rotten                arr[temp.x+1][temp.y] = 2;                 // push the adjacent orange to Queue                temp.x++;                Q.push(temp);                 temp.x--; // Move back to current cell            }             // Check left adjacent cell that if it can be rotten            if (isvalid(temp.x-1, temp.y) && arr[temp.x-1][temp.y] == 1) {                if (!flag) ans++, flag = true;                arr[temp.x-1][temp.y] = 2;                temp.x--;                Q.push(temp); // push this cell to Queue                temp.x++;            }             // Check top adjacent cell that if it can be rotten            if (isvalid(temp.x, temp.y+1) && arr[temp.x][temp.y+1] == 1) {                if (!flag) ans++, flag = true;                arr[temp.x][temp.y+1] = 2;                temp.y++;                Q.push(temp); // Push this cell to Queue                temp.y--;            }             // Check bottom adjacent cell if it can be rotten            if (isvalid(temp.x, temp.y-1) && arr[temp.x][temp.y-1] == 1) {                if (!flag) ans++, flag = true;                arr[temp.x][temp.y-1] = 2;                temp.y--;                Q.push(temp); // push this cell to Queue            }             Q.pop();        }         // Pop the delimiter        Q.pop();         // If oranges were rotten in current frame than separate the        // rotten oranges using delimiter for the next frame for processing.        if (!Q.empty()) {            temp.x = -1;            temp.y = -1;            Q.push(temp);        }         // If Queue was empty than no rotten oranges left to process so exit    }     // Return -1 if all arranges could not rot, otherwise return ans.    return (checkall(arr))? -1: ans;} // Driver programint main(){    int arr[][C] = { {2, 1, 0, 2, 1},                     {1, 0, 1, 2, 1},                     {1, 0, 0, 2, 1}};    int ans = rotOranges(arr);    if (ans == -1)        cout << "All oranges cannot rotn";    else         cout << "Time required for all oranges to rot => " << ans << endl;    return 0;}
//Java program to find minimum time required to make all//oranges rotten import java.util.LinkedList;import java.util.Queue; public class RotOrange{    public final static int R = 3;    public final static int C = 5;         // structure for storing coordinates of the cell    static class Ele    {        int x = 0;        int y = 0;        Ele(int x,int y)        {            this.x = x;            this.y = y;        }    }         // function to check whether a cell is valid / invalid    static boolean isValid(int i, int j)    {        return (i >= 0 && j >= 0 && i < R && j < C);    }          // Function to check whether the cell is delimiter    // which is (-1, -1)    static boolean isDelim(Ele temp)    {        return (temp.x == -1 && temp.y == -1);    }         // Function to check whether there is still a fresh    // orange remaining    static boolean checkAll(int arr[][])    {         for (int i=0; i<R; i++)               for (int j=0; j<C; j++)                  if (arr[i][j] == 1)                     return true;         return false;    }         // This function finds if it is possible to rot all oranges or not.    // If possible, then it returns minimum time required to rot all,    // otherwise returns -1    static int rotOranges(int arr[][])    {        // Create a queue of cells        Queue<Ele> Q=new LinkedList<>();        Ele temp;        int ans = 0;         // Store all the cells having rotten orange in first time frame        for (int i=0; i < R; i++)           for (int j=0; j < C; j++)               if (arr[i][j] == 2)                   Q.add(new Ele(i,j));                         // Separate these rotten oranges from the oranges which will rotten        // due the oranges in first time frame using delimiter which is (-1, -1)        Q.add(new Ele(-1,-1));                 // Process the grid while there are rotten oranges in the Queue        while(!Q.isEmpty())        {            // This flag is used to determine whether even a single fresh            // orange gets rotten due to rotten oranges in the current time            // frame so we can increase the count of the required time.            boolean flag = false;                         // Process all the rotten oranges in current time frame.            while(!isDelim(Q.peek()))            {                temp = Q.peek();                                 // Check right adjacent cell that if it can be rotten                if(isValid(temp.x+1, temp.y) && arr[temp.x+1][temp.y] == 1)                {                    if(!flag)                    {                        // if this is the first orange to get rotten, increase                        // count and set the flag.                        ans++;                        flag = true;                    }                    // Make the orange rotten                    arr[temp.x+1][temp.y] = 2;                                         // push the adjacent orange to Queue                    temp.x++;                    Q.add(new Ele(temp.x,temp.y));                                         // Move back to current cell                    temp.x--;                }                                 // Check left adjacent cell that if it can be rotten                if (isValid(temp.x-1, temp.y) && arr[temp.x-1][temp.y] == 1)                 {                        if (!flag)                        {                            ans++;                            flag = true;                        }                        arr[temp.x-1][temp.y] = 2;                        temp.x--;                        Q.add(new Ele(temp.x,temp.y)); // push this cell to Queue                        temp.x++;                 }                                 // Check top adjacent cell that if it can be rotten                 if (isValid(temp.x, temp.y+1) && arr[temp.x][temp.y+1] == 1) {                        if(!flag)                        {                            ans++;                            flag = true;                        }                        arr[temp.x][temp.y+1] = 2;                        temp.y++;                        Q.add(new Ele(temp.x,temp.y)); // Push this cell to Queue                        temp.y--;                    }                                   // Check bottom adjacent cell if it can be rotten                 if (isValid(temp.x, temp.y-1) && arr[temp.x][temp.y-1] == 1)                 {                        if (!flag)                        {                            ans++;                            flag = true;                        }                        arr[temp.x][temp.y-1] = 2;                        temp.y--;                        Q.add(new Ele(temp.x,temp.y)); // push this cell to Queue                 }                 Q.remove();                              }            // Pop the delimiter            Q.remove();                         // If oranges were rotten in current frame than separate the            // rotten oranges using delimiter for the next frame for processing.            if (!Q.isEmpty())            {                Q.add(new Ele(-1,-1));            }                         // If Queue was empty than no rotten oranges left to process so exit        }                 // Return -1 if all arranges could not rot, otherwise ans        return (checkAll(arr))? -1: ans;             }         // Driver program    public static void main(String[] args)    {        int arr[][] = { {2, 1, 0, 2, 1},                        {1, 0, 1, 2, 1},                        {1, 0, 0, 2, 1}};        int ans = rotOranges(arr);        if(ans == -1)            System.out.println("All oranges cannot rot");        else            System.out.println("Time required for all oranges to rot = " + ans);    } }//This code is contributed by Sumit Ghosh
# Python3 program to find minimum time required to make all# oranges rottenfrom collections import deque # function to check whether a cell is valid / invaliddef isvalid(i, j):    return (i >= 0 and j >= 0 and i < 3 and j < 5) # Function to check whether the cell is delimiter# which is (-1, -1)def isdelim(temp):    return (temp[0] == -1 and temp[1] == -1) # Function to check whether there is still a fresh# orange remainingdef checkall(arr):    for i in range(3):       for j in range(5):          if (arr[i][j] == 1):             return True    return False # This function finds if it is# possible to rot all oranges or not.# If possible, then it returns# minimum time required to rot all,# otherwise returns -1def rotOranges(arr):       # Create a queue of cells    Q = deque()    temp = [0, 0]    ans = 1     # Store all the cells having    # rotten orange in first time frame    for i in range(3):       for j in range(5):            if (arr[i][j] == 2):                temp[0]= i                temp[1] = j                Q.append([i, j])     # Separate these rotten oranges    # from the oranges which will rotten    # due the oranges in first time    # frame using delimiter which is (-1, -1)    temp[0] = -1    temp[1] = -1    Q.append([-1, -1])    # print(Q)     # Process the grid while there are    # rotten oranges in the Queue    while False:               # This flag is used to determine        # whether even a single fresh        # orange gets rotten due to rotten        # oranges in current time        # frame so we can increase        # the count of the required time.        flag = False        print(len(Q))         # Process all the rotten        # oranges in current time frame.        while not isdelim(Q[0]):            temp = Q[0]            print(len(Q))             # Check right adjacent cell that if it can be rotten            if (isvalid(temp[0] + 1, temp[1]) and arr[temp[0] + 1][temp[1]] == 1):                                 # if this is the first orange to get rotten, increase                # count and set the flag.                if (not flag):                    ans, flag =ans + 1, True                 # Make the orange rotten                arr[temp[0] + 1][temp[1]] = 2                 # append the adjacent orange to Queue                temp[0] += 1                Q.append(temp)                 temp[0] -= 1 # Move back to current cell             # Check left adjacent cell that if it can be rotten            if (isvalid(temp[0] - 1, temp[1]) and arr[temp[0] - 1][temp[1]] == 1):                if (not flag):                    ans, flag =ans + 1, True                arr[temp[0] - 1][temp[1]] = 2                temp[0] -= 1                Q.append(temp) # append this cell to Queue                temp[0] += 1             # Check top adjacent cell that if it can be rotten            if (isvalid(temp[0], temp[1] + 1) and arr[temp[0]][temp[1] + 1] == 1):                if (not flag):                    ans, flag = ans + 1, True                arr[temp[0]][temp[1] + 1] = 2                temp[1] += 1                Q.append(temp) # Push this cell to Queue                temp[1] -= 1             # Check bottom adjacent cell if it can be rotten            if (isvalid(temp[0], temp[1] - 1) and arr[temp[0]][temp[1] - 1] == 1):                if (not flag):                    ans, flag = ans + 1, True                arr[temp[0]][temp[1] - 1] = 2                temp[1] -= 1                Q.append(temp) # append this cell to Queue            Q.popleft()         # Pop the delimiter        Q.popleft()         # If oranges were rotten in        # current frame than separate the        # rotten oranges using delimiter        # for the next frame for processing.        if (len(Q) == 0):            temp[0] = -1            temp[1] = -1            Q.append(temp)         # If Queue was empty than no rotten oranges left to process so exit     # Return -1 if all arranges could not rot, otherwise return ans.    return ans + 1 if(checkall(arr)) else -1 # Driver programif __name__ == '__main__':    arr = [[2, 1, 0, 2, 1],         [1, 0, 1, 2, 1],         [1, 0, 0, 2, 1]]    ans = rotOranges(arr)    if (ans == -1):        print("All oranges cannot rotn")    else:        print("Time required for all oranges to rot => " , ans)         # This code is contributed by mohit kumar 29
// C# program to find minimum time// required to make all oranges rottenusing System;using System.Collections.Generic; class GFG{    public const int R = 3;    public const int C = 5;     // structure for storing    // coordinates of the cell    public class Ele    {        public int x = 0;        public int y = 0;        public Ele(int x, int y)        {            this.x = x;            this.y = y;        }    }     // function to check whether a cell    // is valid / invalid    public static bool isValid(int i, int j)    {        return (i >= 0 && j >= 0 &&                i < R && j < C);    }      // Function to check whether the cell    // is delimiter which is (-1, -1)    public static bool isDelim(Ele temp)    {        return (temp.x == -1 && temp.y == -1);    }     // Function to check whether there    // is still a fresh orange remaining    public static bool checkAll(int[][] arr)    {        for (int i = 0; i < R; i++)        {            for (int j = 0; j < C; j++)            {                if (arr[i][j] == 1)                {                    return true;                }            }        }        return false;    }     // This function finds if it is possible    // to rot all oranges or not. If possible,    // then it returns minimum time required    // to rot all, otherwise returns -1    public static int rotOranges(int[][] arr)    {        // Create a queue of cells        LinkedList<Ele> Q = new LinkedList<Ele>();        Ele temp;        int ans = 0;                 // Store all the cells having rotten        // orange in first time frame        for (int i = 0; i < R; i++)        {        for (int j = 0; j < C; j++)        {            if (arr[i][j] == 2)            {                Q.AddLast(new Ele(i, j));            }        }        }         // Separate these rotten oranges from        // the oranges which will rotten        // due the oranges in first time frame        // using delimiter which is (-1, -1)        Q.AddLast(new Ele(-1,-1));         // Process the grid while there are        // rotten oranges in the Queue        while (Q.Count > 0)        {            // This flag is used to determine            // whether even a single fresh            // orange gets rotten due to rotten            // oranges in current time frame so            // we can increase the count of the            // required time.            bool flag = false;             // Process all the rotten oranges            // in current time frame.            while (!isDelim(Q.First.Value))            {                temp = Q.First.Value;                 // Check right adjacent cell that                // if it can be rotten                if (isValid(temp.x + 1, temp.y) &&                        arr[temp.x + 1][temp.y] == 1)                {                    if (!flag)                    {                        // if this is the first orange                        // to get rotten, increase                        // count and set the flag.                        ans++;                        flag = true;                    }                                         // Make the orange rotten                    arr[temp.x + 1][temp.y] = 2;                     // push the adjacent orange to Queue                    temp.x++;                    Q.AddLast(new Ele(temp.x,temp.y));                     // Move back to current cell                    temp.x--;                }                 // Check left adjacent cell that                // if it can be rotten                if (isValid(temp.x - 1, temp.y) &&                        arr[temp.x - 1][temp.y] == 1)                {                        if (!flag)                        {                            ans++;                            flag = true;                        }                        arr[temp.x - 1][temp.y] = 2;                        temp.x--;                                                 // push this cell to Queue                        Q.AddLast(new Ele(temp.x,temp.y));                        temp.x++;                }                 // Check top adjacent cell that                // if it can be rotten                if (isValid(temp.x, temp.y + 1) &&                        arr[temp.x][temp.y + 1] == 1)                {                        if (!flag)                        {                            ans++;                            flag = true;                        }                        arr[temp.x][temp.y + 1] = 2;                        temp.y++;                                                 // Push this cell to Queue                        Q.AddLast(new Ele(temp.x,temp.y));                        temp.y--;                }                 // Check bottom adjacent cell                // if it can be rotten                if (isValid(temp.x, temp.y - 1) &&                        arr[temp.x][temp.y - 1] == 1)                {                        if (!flag)                        {                            ans++;                            flag = true;                        }                        arr[temp.x][temp.y - 1] = 2;                        temp.y--;                                                 // push this cell to Queue                        Q.AddLast(new Ele(temp.x,temp.y));                }                Q.RemoveFirst();             }                         // Pop the delimiter            Q.RemoveFirst();             // If oranges were rotten in current            // frame than separate the rotten            // oranges using delimiter for the            // next frame for processing.            if (Q.Count > 0)            {                Q.AddLast(new Ele(-1,-1));            }             // If Queue was empty than no rotten            // oranges left to process so exit        }         // Return -1 if all arranges could        // not rot, otherwise ans        return (checkAll(arr)) ? -1: ans;     }     // Driver Code    public static void Main(string[] args)    {        int[][] arr = new int[][]        {            new int[] {2, 1, 0, 2, 1},            new int[] {1, 0, 1, 2, 1},            new int[] {1, 0, 0, 2, 1}        };                 int ans = rotOranges(arr);        if (ans == -1)        {            Console.WriteLine("All oranges cannot rot");        }        else        {            Console.WriteLine("Time required for all " +                              "oranges to rot => " + ans);        }    }} // This code is contributed by Shrikant13
Time required for all oranges to rot => 2
Complexity Analysis: Time Complexity: O( R *C). Each element of the matrix can be inserted into the queue only once so the upper bound of iteration is O(R*C), i.e. the number of elements. So time complexity is O(R *C).Space Complexity: O(R*C). To store the elements in a queue O(R*C) space is needed.
Time Complexity: O( R *C). Each element of the matrix can be inserted into the queue only once so the upper bound of iteration is O(R*C), i.e. the number of elements. So time complexity is O(R *C).
Space Complexity: O(R*C). To store the elements in a queue O(R*C) space is needed.
Thanks to Gaurav Ahirwar for suggesting the above solution.Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above 
shrikanth13
arpitn30
gp6
md1844
andrew1234
Akanksha_Rai
ukasp
harshverma31
divyeshrabadiya07
divyesh072019
mohit kumar 29
mukesh07
bicky jaiswal
surinderdawra388
Accolite
Amazon
BFS
MakeMyTrip
Microsoft
Samsung
Graph
Matrix
Queue
Accolite
Amazon
Microsoft
Samsung
MakeMyTrip
Matrix
Graph
Queue
BFS
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Kruskal’s Minimum Spanning Tree Algorithm | Greedy Algo-2
Topological Sorting
Bellman–Ford Algorithm | DP-23
Floyd Warshall Algorithm | DP-16
Detect Cycle in a Directed Graph
Matrix Chain Multiplication | DP-8
Program to find largest element in an array
Rat in a Maze | Backtracking-2
Print a given matrix in spiral form
Sudoku | Backtracking-7