Rotten Oranges - Minimum Time to Rot All

Last Updated : 6 Nov, 2025

Given a matrix mat[][], 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

Find the minimum time required so that all the oranges become rotten. A rotten orange at index (i,j) can rot other fresh oranges which are its neighbours (up, down, left, and right). Each rotten orange takes 1 unit of time to rot all its adjacent fresh oranges.

Note : If it is impossible to rot every orange then simply return -1.

Examples: 

Input:  mat[][] = [[2, 1, 0, 2, 1],
[1, 0, 1, 2, 1],
[1, 0, 0, 2, 1]]
Output: 2
Explanation:

2345

Input:  mat[][] = [[2, 1, 0, 2, 1],
[0, 0, 1, 2, 1],
[1, 0, 0, 2, 1]]
Output: -1
Explanation:

12345
Try it on GfG Practice
redirect icon

[Naive Approach] - Using Iteration - O((n x m) ^ 2) Time and O(1) Space

We know that at each time unit, every rotten orange (2) can rot its adjacent fresh oranges (1). So, we start by traversing the matrix and at time = 0, for every rotten orange, we rot its adjacent fresh oranges.
However, we must ensure that freshly rotted oranges do not rot others within the same time unit, otherwise it will cause incorrect overlapping updates.

To handle this properly: Whenever a rotten orange at cell (i, j) rots a fresh orange, we update that fresh orange’s value to mat[i][j] + 1. This way, oranges that become rotten at time t will have a value t + 2, meaning at the next time step (t + 1), they can start infecting their neighbors.
This process continues as long as at least one fresh orange is rotted in a given iteration.The moment no more oranges can be rotted, the last time value we used indicates the minimum time required to rot all oranges.
Finally, we perform a check to see if any fresh oranges (1s) are still left in the grid:

  • If yes - it means not all oranges could rot, so we return -1.
  • Otherwise - return the last computed time as the result.
C++
//Driver Code Starts
#include <iostream>
#include<vector>
using namespace std;

//Driver Code Ends

bool isSafe(int i, int j, int n, int m) {
    return 0 <= i && i < n && 0 <= j && j < m;
}

int orangesRot(vector<vector<int>>& mat) {
    int n = mat.size();
    int m = mat[0].size();

    // to check if any changes are made
    bool changed;

    // counter of elapsed time
    int elapsedTime = 0;

    // all four directions
    vector<vector<int>> directions = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};

    // iterate until changes are there
    while (true) {
        changed = false;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                
                // check if the cell was marked in last iteration
                if (mat[i][j] == elapsedTime + 2) {
                    
                    // change 4-directionally connected cells
                    for (auto& dir : directions) {
                        int x = i + dir[0];
                        int y = j + dir[1];
                        
                        // if cell is in the matrix and the
                        //orange is fresh
                        if (isSafe(x, y, n, m) && mat[x][y] == 1) {
                            mat[x][y] = mat[i][j] + 1;
                            changed = true;
                        }
                    }
                }
            }
        }
        
        // if no changes are done
        if (!changed) {
            break;
        }
        elapsedTime++;
    }

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            
            // if any orange is found not rotten, return -1
            if (mat[i][j] == 1) {
                return -1;
            }
        }
    }

    return elapsedTime;
}

//Driver Code Starts

int main() {
    vector<vector<int>> mat = {{2, 1, 0, 2, 1}, {1, 0, 1, 2, 1}, {1, 0, 0, 2, 1}};
    cout << orangesRot(mat) << endl;
    return 0;
}
//Driver Code Ends
Java
//Driver Code Starts

public class GfG {
   
//Driver Code Ends

    private boolean isSafe(int i, int j, int n, int m) {
        return 0 <= i && i < n && 0 <= j && j < m;
    }

    public int orangesRot(int[][] mat) {
        int n = mat.length;
        int m = mat[0].length;

        // to check if any changes are made
        boolean changed;

        // counter of elapsed time
        int elapsedTime = 0;

        // all four directions
        int[][] directions = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};

        // iterate until changes are there
        while (true) {
            changed = false;
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < m; j++) {
                    
                    // check if the cell was marked in last iteration
                    if (mat[i][j] == elapsedTime + 2) {
                        
                        // change 4-directionally connected cells
                        for (int[] dir : directions) {
                            int x = i + dir[0];
                            int y = j + dir[1];
                            
                            // if cell is in the matrix and the
                            //orange is fresh
                            if (isSafe(x, y, n, m) && mat[x][y] == 1) {
                                mat[x][y] = mat[i][j] + 1;
                                changed = true;
                            }
                        }
                    }
                }
            }
            
            // if no changes are done
            if (!changed) {
                break;
            }
            elapsedTime++;
        }

        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                
                // if any orange is found not rotten, return -1
                if (mat[i][j] == 1) {
                    return -1;
                }
            }
        }

        return elapsedTime;
    }

//Driver Code Starts

    public static void main(String[] args) {
        int[][] mat = {{2, 1, 0, 2, 1}, {1, 0, 1, 2, 1}, {1, 0, 0, 2, 1}};
        GfG sol = new GfG();
        System.out.println(sol.orangesRot(mat));
    }
}
//Driver Code Ends
Python
def isSafe(i, j, n, m):
    return 0 <= i < n and 0 <= j < m

def orangesRot(mat):
    n = len(mat)
    m = len(mat[0])

    # to check if any changes are made
    changed = False

    # counter of elapsed time
    elapsedTime = 0

    # all four directions
    directions = [[1, 0], [0, 1], [-1, 0], [0, -1]]

    # iterate until changes are there
    while True:
        for i in range(n):
            for j in range(m):

                # check if the cell was marked in last iteration
                if mat[i][j] == elapsedTime + 2:

                    # change 4-directionally connected cells
                    for dir in directions:
                        x = i + dir[0]
                        y = j + dir[1]

                        # if cell is in the matrix and
                        # the orange is fresh
                        if isSafe(x, y, n, m) and mat[x][y] == 1:
                            mat[x][y] = mat[i][j] + 1
                            changed = True

        # if no changes are done
        if not changed:
            break
        changed = False
        elapsedTime += 1

    for i in range(n):
        for j in range(m):

            # if any orange is found
            # not rotten, return -1
            if mat[i][j] == 1:
                return -1

    return elapsedTime


#Driver Code Starts
if __name__ == "__main__":
    mat =  [ [2, 1, 0, 2, 1], [1, 0, 1, 2, 1], [1, 0, 0, 2, 1] ]
    
    print(orangesRot(mat))

#Driver Code Ends
C#
//Driver Code Starts
using System;
using System.Collections.Generic;

class GfG {
//Driver Code Ends

    static bool isSafe(int i, int j, int n, int m) {
        return (i >= 0 && i < n && j >= 0 && j < m);
    }

    static int orangesRot(int[,] mat) {
        int n = mat.GetLength(0);
        int m = mat.GetLength(1);

        // to check if any changes are made
        bool changed = false;

        // counter of elapsed time
        int elapsedTime = 0;

        // all four directions
        int[,] directions = new int[,] {
            { 1, 0 }, { 0, 1 },
            { -1, 0 }, { 0, -1 }
        };

        // iterate until changes are there
        while (true) {
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < m; j++) {

                    // check if the cell was marked in last iteration
                    if (mat[i, j] == elapsedTime + 2) {

                        // change 4-directionally connected cells
                        for (int d = 0; d < 4; d++) {
                            int x = i + directions[d, 0];
                            int y = j + directions[d, 1];

                            // if cell is in the matrix and
                            // the orange is fresh
                            if (isSafe(x, y, n, m) && mat[x, y] == 1) {
                                mat[x, y] = mat[i, j] + 1;
                                changed = true;
                            }
                        }
                    }
                }
            }

            // if no changes are done
            if (!changed) break;
            changed = false;
            elapsedTime++;
        }

        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {

                // if any orange is found
                // not rotten, return -1
                if (mat[i, j] == 1) return -1;
            }
        }

        return elapsedTime;
    }

//Driver Code Starts

    static void Main(string[] args) {
        int[,] mat = {
            {2, 1, 0, 2, 1},
            {1, 0, 1, 2, 1},
            {1, 0, 0, 2, 1}
        };

        Console.WriteLine(orangesRot(mat));
    }
}

//Driver Code Ends
JavaScript
function isSafe(i, j, n, m) {
    return i >= 0 && i < n && j >= 0 && j < m;
}

function orangesRot(mat) {
    let n = mat.length;
    let m = mat[0].length;

    // to check if any changes are made
    let changed = false;

    // counter of elapsed time
    let elapsedTime = 0;

    // all four directions
    const directions = [[1, 0], [0, 1], [-1, 0], [0, -1]];

    // iterate until changes are there
    while (true) {
        for (let i = 0; i < n; i++) {
            for (let j = 0; j < m; j++) {

                // check if the cell was marked in last iteration
                if (mat[i][j] === elapsedTime + 2) {

                    // change 4-directionally connected cells
                    for (const dir of directions) {
                        let x = i + dir[0];
                        let y = j + dir[1];

                        // if cell is in the matrix and
                        // the orange is fresh
                        if (isSafe(x, y, n, m) && mat[x][y] === 1) {
                            mat[x][y] = mat[i][j] + 1;
                            changed = true;
                        }
                    }
                }
            }
        }

        // if no changes are done
        if (!changed) break;
        changed = false;
        elapsedTime++;
    }

    for (let i = 0; i < n; i++) {
        for (let j = 0; j < m; j++) {

            // if any orange is found
            // not rotten, return -1
            if (mat[i][j] === 1) return -1;
        }
    }

    return elapsedTime;
}


//Driver Code Starts
// Driver Code
const mat = [
    [2, 1, 0, 2, 1], [1, 0, 1, 2, 1], [1, 0, 0, 2, 1] 
];

console.log(orangesRot(mat));

//Driver Code Ends

Output
2

[Better Approach] - Using Depth First Search - O(n x m) Time and O(1) Space

The idea is to use DFS (Depth-First Search) because DFS explores deeply in one direction before backtracking. This property helps us simulate how the rot spreads from one orange to another over time.

We start by iterating through the entire matrix, and whenever we find a rotten orange (2), we begin a DFS from that cell. During the DFS, we go to all its adjacent cells and record the time when each orange becomes rotten.
If a neighboring cell contains a fresh orange (1), that means it can now become rotten, so we recursively call DFS for that cell with the time current_time + 1.
If a cell was already rotten earlier but now can rot in less time, we update its time and continue DFS from that cell again.

In this way, DFS helps us spread the rot recursively throughout the grid while keeping track of the minimum time taken for each orange to rot. After all DFS calls are complete, we iterate through the entire matrix once again.If we find any fresh orange still left, it means it was unreachable, so we return -1.
Otherwise, we take the maximum recorded time — which represents the minimum time required to rot all the oranges.

C++
//Driver Code Starts
#include <iostream>
#include<vector>
using namespace std;

//Driver Code Ends

bool isSafe(int i, int j, int n, int m)
{
    return (i >= 0 && i < n && j >= 0 && j < m);
}

// function to perform dfs and find fresh orange
void dfs(vector<vector<int>> &mat, int i, int j, int time)
{
    int n = mat.size();
    int m = mat[0].size();

    // update minimum time
    mat[i][j] = time;

    // all four directions
    vector<vector<int>> directions = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};

    // change 4-directionally connected cells
    for (auto dir : directions)
    {
        int x = i + dir[0];
        int y = j + dir[1];

        // if cell is in the matrix and
        // the orange is fresh
        if (isSafe(x, y, n, m) && (mat[x][y] == 1 || mat[x][y] > time + 1))
        {
            dfs(mat, x, y, time + 1);
        }
    }
}

int orangesRot(vector<vector<int>> &mat)
{
    int n = mat.size();
    int m = mat[0].size();

    // counter of elapsed time
    int elapsedTime = 0;

    // iterate through all the cells
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < m; j++)
        {

            // if orange is initiall rotten
            if (mat[i][j] == 2)
            {
                dfs(mat, i, j, 2);
            }
        }
    }
    // iterate through all the cells
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < m; j++)
        {

            // if orange is fresh
            if (mat[i][j] == 1)
                return -1;

            // update the maximum time
            elapsedTime = max(elapsedTime, mat[i][j] - 2);
        }
    }
    return elapsedTime;
}

//Driver Code Starts

int main()
{   
    vector<vector<int>> mat = {{2, 1, 0, 2, 1}, {1, 0, 1, 2, 1}, {1, 0, 0, 2, 1}};
    cout << orangesRot(mat);
    return 0;
}
//Driver Code Ends
Java
//Driver Code Starts

class GfG {

//Driver Code Ends

    static boolean isSafe(int i, int j, int n, int m)
    {
        return (i >= 0 && i < n && j >= 0 && j < m);
    }

    // function to perform dfs and find fresh orange
    static void dfs(int[][] mat, int i, int j, int time)
    {
        int n = mat.length;
        int m = mat[0].length;

        // update minimum time
        mat[i][j] = time;

        // all four directions
        int[][] directions
            = {{1, 0},{0, 1}, {-1, 0},{0, -1}};

        // change 4-directionally connected cells
        for (int[] dir : directions) {
            int x = i + dir[0];
            int y = j + dir[1];

            // if cell is in the matrix and
            // the orange is fresh
            if (isSafe(x, y, n, m)
                && (mat[x][y] == 1
                    || mat[x][y] > time + 1)) {
                dfs(mat, x, y, time + 1);
            }
        }
    }

    static int orangesRot(int[][] mat)
    {
        int n = mat.length;
        int m = mat[0].length;

        // counter of elapsed time
        int elapsedTime = 0;

        // iterate through all the cells
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {

                // if orange is initially rotten
                if (mat[i][j] == 2) {
                    dfs(mat, i, j, 2);
                }
            }
        }

        // iterate through all the cells
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {

                // if orange is fresh
                if (mat[i][j] == 1)
                    return -1;

                // update the maximum time
                elapsedTime
                    = Math.max(elapsedTime, mat[i][j] - 2);
            }
        }
        return elapsedTime;
    }

//Driver Code Starts

    public static void main(String[] args)
    {
        int[][] mat
            = {{2, 1, 0, 2, 1}, {1, 0, 1, 2, 1}, {1, 0, 0, 2, 1}};
        System.out.println(orangesRot(mat));
    }
}
//Driver Code Ends
Python
def isSafe(i, j, n, m):
    return 0 <= i < n and 0 <= j < m

# function to perform dfs and find fresh orange
def dfs(mat, i, j, time):
    n = len(mat)
    m = len(mat[0])

    # update minimum time
    mat[i][j] = time

    # all four directions
    directions = [[1, 0], [0, 1], [-1, 0], [0, -1]]

    # change 4-directionally connected cells
    for dir in directions:
        x = i + dir[0]
        y = j + dir[1]

        # if cell is in the matrix and
        # the orange is fresh
        if isSafe(x, y, n, m) and (mat[x][y] == 1 or mat[x][y] > time + 1):
            dfs(mat, x, y, time + 1)


def orangesRot(mat):
    n = len(mat)
    m = len(mat[0])

    # counter of elapsed time
    elapsedTime = 0

    # iterate through all the cells
    for i in range(n):
        for j in range(m):

            # if orange is initially rotten
            if mat[i][j] == 2:
                dfs(mat, i, j, 2)

    # iterate through all the cells
    for i in range(n):
        for j in range(m):

            # if orange is fresh
            if mat[i][j] == 1:
                return -1

            # update the maximum time
            elapsedTime = max(elapsedTime, mat[i][j] - 2)

    return    elapsedTime


#Driver Code Starts

if __name__ == "__main__":
    mat = [[2, 1, 0, 2, 1],
          [1, 0, 1, 2, 1],
          [1, 0, 0, 2, 1]]

    print(orangesRot(mat))
#Driver Code Ends
C#
//Driver Code Starts
using System;

class GfG {

//Driver Code Ends

    static bool isSafe(int i, int j, int n, int m)
    {
        return (i >= 0 && i < n && j >= 0 && j < m);
    }

    // function to perform dfs and find fresh orange
    static void dfs(int[,] mat, int i, int j, int time)
    {
        int n = mat.GetLength(0);
        int m = mat.GetLength(1);

        // update minimum time
        mat[i, j] = time;

        // all four directions
        int[,] directions = {
            { 1, 0 }, { 0, 1 },
            { -1, 0 }, { 0, -1 }
        };

        // change 4-directionally connected cells
        for (int d = 0; d < 4; d++)
        {
            int x = i + directions[d, 0];
            int y = j + directions[d, 1];

            // if cell is in the matrix and
            // the orange is fresh
            if (isSafe(x, y, n, m)
                && (mat[x, y] == 1
                    || mat[x, y] > time + 1))
            {
                dfs(mat, x, y, time + 1);
            }
        }
    }

    static int orangesRot(int[,] mat)
    {
        int n = mat.GetLength(0);
        int m = mat.GetLength(1);

        // counter of elapsed time
        int elapsedTime = 0;

        // iterate through all the cells
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {

                // if orange is initially rotten
                if (mat[i, j] == 2) {
                    dfs(mat, i, j, 2);
                }
            }
        }

        // iterate through all the cells
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {

                // if orange is fresh
                if (mat[i, j] == 1)
                    return -1;

                // update the maximum time
                elapsedTime = Math.Max(elapsedTime, mat[i, j] - 2);
            }
        }
        return elapsedTime;
    }

//Driver Code Starts

    static void Main(string[] args)
    {
        int[,] mat = {
            { 2, 1, 0, 2, 1 },
            { 1, 0, 1, 2, 1 },
            { 1, 0, 0, 2, 1 }
        };

        Console.WriteLine(orangesRot(mat));
    }
}

//Driver Code Ends
JavaScript
function isSafe(i, j, n, m)
{
    return i >= 0 && i < n && j >= 0 && j < m;
}

// function to perform dfs and find fresh orange
function dfs(mat, i, j, time)
{
    const n = mat.length;
    const m = mat[0].length;

    // update minimum time
    mat[i][j] = time;

    // all four directions
    const directions =
        [ [ 1, 0 ], [ 0, 1 ], [ -1, 0 ], [ 0, -1 ] ];

    // change 4-directionally connected cells
    for (const dir of directions) {
        const x = i + dir[0];
        const y = j + dir[1];

        // if cell is in the matrix and
        // the orange is fresh
        if (isSafe(x, y, n, m)
            && (mat[x][y] === 1 || mat[x][y] > time + 1)) {
            dfs(mat, x, y, time + 1);
        }
    }
}

function orangesRot(mat)
{
    const n = mat.length;
    const m = mat[0].length;

    // counter of elapsed time
    let elapsedTime = 0;

    // iterate through all the cells
    for (let i = 0; i < n; i++) {
        for (let j = 0; j < m; j++) {

            // if orange is initially rotten
            if (mat[i][j] === 2) {
                dfs(mat, i, j, 2);
            }
        }
    }

    // iterate through all the cells
    for (let i = 0; i < n; i++) {
        for (let j = 0; j < m; j++) {

            // if orange is fresh
            if (mat[i][j] === 1)
                return -1;

            // update the maximum time
            elapsedTime
                = Math.max(elapsedTime, mat[i][j] - 2);
        }
    }
    return elapsedTime;
}


//Driver Code Starts
// Driver Code
const mat = [
    [2, 1, 0, 2, 1], [1, 0, 1, 2, 1], [1, 0, 0, 2, 1]
];

console.log(orangesRot(mat));
//Driver Code Ends

Output
2

[Expected Approach] - Using Breadth First Search - O(n x m) Time and O(n x m) Space

The idea is to use BFS (Breadth-First Search) because BFS explores the grid level by level. In DFS, we can not say that a fresh orange getting rotten from another rotten orange represents its minimum time to rot because DFS explores deeply in one direction. However, in BFS ensuring that when a fresh orange becomes rotten, it is always at the earliest possible time.

To apply this idea, we first add all the initially rotten oranges to a queue. Then, we process them one by one from the queue. For each rotten orange, we check its four neighboring cells. If a neighbor is a fresh orange (1), it becomes rotten, and we push it into the queue. As BFS moves level by level, we also keep track of a variable to record the time taken — this value increases with each level processed.
Once the queue becomes empty, it means all possible oranges have been processed. Finally, we check the grid again — if any fresh orange is still left, it means it couldn’t be reached, so we return -1. Otherwise, the maximum time recorded gives us the minimum time required to rot all the oranges.

Illustration:

C++
//Driver Code Starts
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
//Driver Code Ends


bool isSafe(int i, int j, int n, int m)
{
    return (i >= 0 && i < n && j >= 0 && j < m);
}

// function to perform bfs and find minimum time
int orangesRot(vector<vector<int>> &mat)
{
    int n = mat.size();
    int m = mat[0].size();

    // queue to store coordinates of rotten oranges
    queue<pair<int, int>> q;

    // counter of elapsed time
    int elapsedTime = 0;

    // push all initially rotten oranges into queue
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < m; j++)
        {
            if (mat[i][j] == 2)
            {
                q.push({i, j});
            }
        }
    }

    // directions for all four adjacent cells
    vector<vector<int>> directions = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};

    // perform BFS
    while (!q.empty())
    {
        int size = q.size();
        bool flag = false; 

        // process all oranges at current time level
        for (int i = 0; i < size; i++)
        {
            auto [x, y] = q.front();
            q.pop();

            // check all four directions
            for (auto dir : directions)
            {
                int nx = x + dir[0];
                int ny = y + dir[1];

                // if cell is safe and has fresh orange
                if (isSafe(nx, ny, n, m) && mat[nx][ny] == 1)
                {
                    // rot the orange
                    mat[nx][ny] = 2;
                    q.push({nx, ny});
                    flag = true;
                }
            }
        }

        // if at least one orange got rotten, increase the time
        if (flag)
            elapsedTime++;
    }

    // check if any fresh orange still remains
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < m; j++)
        {
            if (mat[i][j] == 1)
                return -1;
        }
    }

    return elapsedTime;
}


//Driver Code Starts
int main()
{
    vector<vector<int>> mat = {{2, 1, 0, 2, 1},
                               {1, 0, 1, 2, 1},
                               {1, 0, 0, 2, 1}};
    cout << orangesRot(mat);
    return 0;
}

//Driver Code Ends
Java
//Driver Code Starts
import java.util.Arrays;
import java.util.Queue;
import java.util.LinkedList;

class GFG {
//Driver Code Ends

    static boolean isSafe(int i, int j, int n, int m) {
        return (i >= 0 && i < n && j >= 0 && j < m);
    }

    // function to perform bfs and find minimum time
    static int orangesRot(int[][] mat) {
        int n = mat.length;
        int m = mat[0].length;

        // queue to store coordinates of rotten oranges
        Queue<int[]> q = new LinkedList<>();

        // counter of elapsed time
        int elapsedTime = 0;

        // push all initially rotten oranges into queue
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (mat[i][j] == 2) {
                    q.add(new int[]{i, j});
                }
            }
        }

        // directions for all four adjacent cells
        int[][] directions = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};

        // perform BFS
        while (!q.isEmpty()) {
            int size = q.size();
            boolean flag = false; 

            // process all oranges at current time level
            for (int i = 0; i < size; i++) {
                int[] cell = q.poll();
                int x = cell[0];
                int y = cell[1];

                // check all four directions
                for (int[] dir : directions) {
                    int nx = x + dir[0];
                    int ny = y + dir[1];

                    // if cell is safe and has fresh orange
                    if (isSafe(nx, ny, n, m) && mat[nx][ny] == 1) {
                        // rot the orange
                        mat[nx][ny] = 2;
                        q.add(new int[]{nx, ny});
                        flag = true;
                    }
                }
            }

            // if at least one orange got rotten, increase the time
            if (flag)
                elapsedTime++;
        }

        // check if any fresh orange still remains
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (mat[i][j] == 1)
                    return -1;
            }
        }

        return elapsedTime;
    }


//Driver Code Starts
    public static void main(String[] args) {
        int[][] mat = {{2, 1, 0, 2, 1},
                       {1, 0, 1, 2, 1},
                       {1, 0, 0, 2, 1}};
        System.out.println(orangesRot(mat));
    }
}

//Driver Code Ends
Python
#Driver Code Starts
from collections import deque
#Driver Code Ends


def isSafe(i, j, n, m):
    return 0 <= i < n and 0 <= j < m

# function to perform bfs and find minimum time
def orangesRot(mat):
    n = len(mat)
    m = len(mat[0])

    # queue to store coordinates of rotten oranges
    q = deque()

    # counter of elapsed time
    elapsedTime = 0

    # push all initially rotten oranges into queue
    for i in range(n):
        for j in range(m):
            if mat[i][j] == 2:
                q.append((i, j))

    # directions for all four adjacent cells
    directions = [(1, 0), (0, 1), (-1, 0), (0, -1)]

    # perform BFS
    while q:
        size = len(q)
        flag = False  

        # process all oranges at current time level
        for _ in range(size):
            x, y = q.popleft()

            # check all four directions
            for dx, dy in directions:
                nx, ny = x + dx, y + dy

                # if cell is safe and has fresh orange
                if isSafe(nx, ny, n, m) and mat[nx][ny] == 1:
                    # rot the orange
                    mat[nx][ny] = 2
                    q.append((nx, ny))
                    flag = True

        # if at least one orange got rotten, increase the time
        if flag:
            elapsedTime += 1

    # check if any fresh orange still remains
    for i in range(n):
        for j in range(m):
            if mat[i][j] == 1:
                return -1

    return elapsedTime


#Driver Code Starts
if __name__ == "__main__":
    mat = [[2, 1, 0, 2, 1],
           [1, 0, 1, 2, 1],
           [1, 0, 0, 2, 1]]
    
    print(orangesRot(mat))

#Driver Code Ends
C#
//Driver Code Starts
using System;
using System.Collections.Generic;

class GFG
{
//Driver Code Ends

    static bool isSafe(int i, int j, int n, int m)
    {
        return (i >= 0 && i < n && j >= 0 && j < m);
    }

    // function to perform bfs and find minimum time
    static int orangesRot(int[,] mat)
    {
        int n = mat.GetLength(0);
        int m = mat.GetLength(1);

        // queue to store coordinates of rotten oranges
        Queue<(int, int)> q = new Queue<(int, int)>();

        // counter of elapsed time
        int elapsedTime = 0;

        // push all initially rotten oranges into queue
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < m; j++)
            {
                if (mat[i, j] == 2)
                    q.Enqueue((i, j));
            }
        }

        // directions for all four adjacent cells
        int[,] directions = { { 1, 0 }, { 0, 1 }, { -1, 0 }, { 0, -1 } };

        // perform BFS
        while (q.Count > 0)
        {
            int size = q.Count;
            bool flag = false; 

            // process all oranges at current time level
            for (int s = 0; s < size; s++)
            {
                var (x, y) = q.Dequeue();

                // check all four directions
                for (int k = 0; k < 4; k++)
                {
                    int nx = x + directions[k, 0];
                    int ny = y + directions[k, 1];

                    // if cell is safe and has fresh orange
                    if (isSafe(nx, ny, n, m) && mat[nx, ny] == 1)
                    {
                        // rot the orange
                        mat[nx, ny] = 2;
                        q.Enqueue((nx, ny));
                        flag = true;
                    }
                }
            }

            // if at least one orange got rotten, increase the time
            if (flag)
                elapsedTime++;
        }

        // check if any fresh orange still remains
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < m; j++)
            {
                if (mat[i, j] == 1)
                    return -1;
            }
        }

        return elapsedTime;
    }


//Driver Code Starts
    static void Main()
    {
        int[,] mat = { { 2, 1, 0, 2, 1 },
                       { 1, 0, 1, 2, 1 },
                       { 1, 0, 0, 2, 1 } };

        Console.WriteLine(orangesRot(mat));
    }
}

//Driver Code Ends
JavaScript
function isSafe(i, j, n, m) {
    return i >= 0 && i < n && j >= 0 && j < m;
}

// function to perform bfs and find minimum time
function orangesRot(mat) {
    const n = mat.length;
    const m = mat[0].length;

    // queue to store coordinates of rotten oranges
    const q = [];

    // counter of elapsed time
    let elapsedTime = 0;

    // push all initially rotten oranges into queue
    for (let i = 0; i < n; i++) {
        for (let j = 0; j < m; j++) {
            if (mat[i][j] === 2) {
                q.push([i, j]);
            }
        }
    }

    // directions for all four adjacent cells
    const directions = [[1, 0], [0, 1], [-1, 0], [0, -1]];

    // perform BFS
    while (q.length > 0) {
        let size = q.length;
        let flag = false;

        // process all oranges at current time level
        for (let s = 0; s < size; s++) {
            const [x, y] = q.shift();

            // check all four directions
            for (const [dx, dy] of directions) {
                const nx = x + dx;
                const ny = y + dy;

                // if cell is safe and has fresh orange
                if (isSafe(nx, ny, n, m) && mat[nx][ny] === 1) {
                    // rot the orange
                    mat[nx][ny] = 2;
                    q.push([nx, ny]);
                    flag = true;
                }
            }
        }

        // if at least one orange got rotten, increase the time
        if (flag) elapsedTime++;
    }

    // check if any fresh orange still remains
    for (let i = 0; i < n; i++) {
        for (let j = 0; j < m; j++) {
            if (mat[i][j] === 1) return -1;
        }
    }

    return elapsedTime;
}

//Driver Code
//Driver Code Starts
const mat = [
    [2, 1, 0, 2, 1],
    [1, 0, 1, 2, 1],
    [1, 0, 0, 2, 1]
];
console.log(orangesRot(mat));

//Driver Code Ends

Output
2
Comment