Rotten Oranges Minimum Time to Rot All (original) (raw)

Given a matrix mat[][], where each cell in the matrix can have values **0, 1 or 2 which has the following meaning:

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

Table of Content

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

C++ `

//Driver Code Starts #include #include 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>& 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> 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

`

[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 #include 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> &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> &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> 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

`

[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 #include #include 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> &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> 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

`