Rotting Oranges medium
Problem Statement
You are given an m x n
grid representing a garden made of oranges. Each cell has one of three values:
0
: empty cell1
: orange that is fresh2
: orange that is rotten
Every minute, any fresh orange that is 4-directionally adjacent (up, down, left, or right) to a rotten orange becomes rotten.
Return the minimum number of minutes that must elapse until no cell has a fresh orange. If this is impossible, return -1
.
Example 1
Input: grid = [[2,1,1],[1,1,0],[0,1,1]]
Output: 4
Example 2
Input: grid = [[2,1,1],[0,1,1],[1,0,1]]
Output: -1
Steps
-
Initialization:
- Create a queue to store the coordinates of initially rotten oranges.
- Count the total number of fresh oranges. We'll use this to check if all oranges have eventually rotted.
- Initialize a variable
minutes
to 0 (to track time).
-
Breadth-First Search (BFS):
- While the queue is not empty:
- Get the size of the queue (number of oranges to process in the current minute).
- Iterate through the oranges in the current queue:
- For each rotten orange at (row, col), explore its four neighbors:
- If a neighbor is a fresh orange (value 1):
- Change its value to 2 (rotten).
- Add its coordinates to the queue.
- Decrement the count of fresh oranges.
- If a neighbor is a fresh orange (value 1):
- For each rotten orange at (row, col), explore its four neighbors:
- Increment
minutes
(one minute has passed).
- While the queue is not empty:
-
Check for Fresh Oranges:
- If the count of fresh oranges is 0, it means all oranges have rotted, and we return
minutes
. - If the queue becomes empty before all fresh oranges have rotted, it means some oranges remain fresh and cannot be reached; return
-1
.
- If the count of fresh oranges is 0, it means all oranges have rotted, and we return
Explanation
The problem can be efficiently solved using Breadth-First Search (BFS). BFS guarantees that we process oranges in the order they become rotten, ensuring we find the minimum time. We use a queue to maintain the order of processing. Each iteration of the outer while loop represents one minute of time elapsing. The inner loop processes all the oranges that became rotten in the previous minute. The count of fresh oranges helps us efficiently determine if all oranges have rotted.
Code
from collections import deque
def oranges_rotting(grid):
rows, cols = len(grid), len(grid[0])
queue = deque()
fresh_count = 0
# Initialize queue 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_count += 1
# No fresh oranges, return 0
if fresh_count == 0:
return 0
minutes = 0
directions = [(0, 1), (0, -1), (1, 0), (-1, 0)]
while queue:
size = len(queue)
for _ in range(size):
row, col = queue.popleft()
for dr, dc in directions:
nr, nc = row + dr, col + dc
if 0 <= nr < rows and 0 <= nc < cols and grid[nr][nc] == 1:
grid[nr][nc] = 2
queue.append((nr, nc))
fresh_count -= 1
minutes += 1
# Check if all fresh oranges have rotted
return minutes if fresh_count == 0 else -1
Complexity
- Time Complexity: O(M * N), where M and N are the dimensions of the grid. We visit each cell at most once.
- Space Complexity: O(M * N) in the worst case, where the queue could hold all the cells in the grid if all oranges are initially rotten.