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:
- 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:
**Input: mat[][] = [[2, 1, 0, 2, 1],
[0, 0, 1, 2, 1],
[1, 0, 0, 2, 1]]
**Output: -1
**Explanation:
Table of Content
- [Naive Approach] - Using Iteration - O((n x m) ^ 2) Time and O(1) Space
- [Better Approach] - Using Depth First Search - O(n x m) Time and O(1) Space
- [Expected Approach] - Using Breadth First Search - O(n x m) Time and O(n x m) Space
[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 #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
`

