You are given an m x n grid where each cell can have one of three values:
0 representing an empty cell, 1 representing a fresh orange, or 2 representing a rotten orange.
Every minute, any fresh orange that is 4-directionally adjacent to a rotten orange becomes rotten.
Return the minimum number of minutes that must elapse until no cell has a fresh orange. If it is impossible, return -1.
For example, consider the following grid:
[[2,1,1], [1,1,0], [0,1,1]]
In this case, the function should return 4 because it takes 4 minutes for all the fresh oranges to rot.
As another example, consider the following grid:
[[2,1,1], [0,1,1], [1,0,1]]
In this case, the function should return -1 because the orange in the bottom left will never rot.
Here's how the rotting process would proceed in the first example:
Initial state:
[[2,1,1], [1,1,0], [0,1,1]]
After 1 minute:
[[2,2,1], [2,1,0], [0,1,1]]
After 2 minutes:
[[2,2,2], [2,2,0], [0,1,1]]
After 3 minutes:
[[2,2,2], [2,2,0], [0,2,1]]
After 4 minutes:
[[2,2,2], [2,2,0], [0,2,2]]
All fresh oranges are now rotten after 4 minutes. Write a function to solve this problem efficiently. Consider edge cases such as an empty grid or a grid with no fresh oranges initially.
You are given an m x n
grid where each cell can have one of three values:
0
representing an empty cell,1
representing a fresh orange, or2
representing a rotten orange.Every minute, any fresh orange that is 4-directionally adjacent to a rotten orange becomes rotten.
Return the minimum number of minutes that must elapse until no cell has a fresh orange. If it is impossible, return -1.
A brute force approach would involve iterating through the grid at each minute, identifying fresh oranges adjacent to rotten oranges, and marking them as rotten. We would continue this process until no more oranges can rot or until a maximum time limit is reached. This approach is inefficient because it involves redundant checks and updates at each minute.
The optimal solution uses Breadth-First Search (BFS) to simulate the rotting process. Here's the algorithm:
Initialization:
BFS Iteration:
Check for Unrotted Oranges:
from collections import deque
def rotting_oranges(grid):
if not grid:
return -1
rows, cols = len(grid), len(grid[0])
queue = deque()
fresh_oranges = 0
# Initialize queue with rotten oranges and count fresh oranges
for r in range(rows):
for c in range(cols):
if grid[r][c] == 2:
queue.append((r, c))
elif grid[r][c] == 1:
fresh_oranges += 1
minutes = 0
directions = [(0, 1), (0, -1), (1, 0), (-1, 0)]
while queue:
# Process all oranges that rotted at the current minute
for _ in range(len(queue)):
row, col = queue.popleft()
# Check adjacent cells
for dr, dc in directions:
new_row, new_col = row + dr, col + dc
if 0 <= new_row < rows and 0 <= new_col < cols and grid[new_row][new_col] == 1:
# Rot the fresh orange
grid[new_row][new_col] = 2
fresh_oranges -= 1
queue.append((new_row, new_col))
# Increment minutes after processing current level
minutes += 1
# If any fresh oranges remain, it's impossible to rot them all
if fresh_oranges > 0:
return -1
# Return the time taken to rot all oranges, subtract 1 because of the last increment
return minutes - 1
# Example Usage
grid1 = [[2,1,1],[1,1,0],[0,1,1]]
print(rotting_oranges(grid1)) # Output: 4
grid2 = [[2,1,1],[0,1,1],[1,0,1]]
print(rotting_oranges(grid2)) # Output: -1
grid3 = [[0,2]]
print(rotting_oranges(grid3)) # Output: 0
grid4 = [[0]]
print(rotting_oranges(grid4)) # Output: 0
grid5 = [[1]]
print(rotting_oranges(grid5)) # Output: -1
The time complexity of the optimal solution is O(m * n), where m is the number of rows and n is the number of columns in the grid.
Therefore, the overall time complexity is O(m * n) + O(m * n) which simplifies to O(m * n).
The space complexity of the optimal solution is O(m * n) in the worst case.
Thus, the overall space complexity is dominated by the queue, which is O(m * n).