Rotting Oranges

Updated on 25 June, 2025
Rotting Oranges header image

Problem Statement

In this problem, you are provided with a matrix (grid) of dimensions m x n, representing a grid where each cell can hold either an empty cell (0), a fresh orange (1), or a rotten orange (2). The task is to simulate the process by which the rotten oranges contaminate the fresh ones. The contamination spreads to fresh oranges that are adjacent in the four cardinal directions (up, down, left, right) at the rate of one minute per step.

Your objective is to determine the minimum number of minutes required for all fresh oranges to become rotten, if possible. If there are fresh oranges that cannot be contaminated by the rotten ones due to isolation, you should return -1 to indicate this impossibility.

Examples

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

Explanation:

The orange in the bottom left corner (row 2, column 0) is never rotten, because rotting only happens 4-directionally.

Example 3

Input:

grid = [[0,2]]

Output:

0

Explanation:

Since there are already no fresh oranges at minute 0, the answer is just 0.

Constraints

  • m == grid.length
  • n == grid[i].length
  • 1 <= m, n <= 10
  • grid[i][j] is 0, 1, or 2.

Approach and Intuition

Given the nature of the problem, which involves spreading from multiple sources over time, a breadth-first search (BFS) strategy using a queue can be effectively implemented here. The intuition behind using BFS is that it perfectly models situations involving levels or steps (in this case, minutes):

  1. Initially, add all the positions of the rotten oranges to a queue and commence BFS.
  2. For each rotten orange, check its four cardinal direction neighbors. If a neighbor is a fresh orange (1), convert it to rotten (2) and add its position to the queue for further processing in the subsequent minute (next level of BFS).
  3. Track the number of minutes using a level counter associated with each BFS level.
  4. Continue the BFS until there are no more fresh oranges adjacent to the rotten ones. Post-BFS, verify if any fresh oranges remain that weren't contaminated (due to isolation). If such oranges exist, return -1.
  5. Otherwise, return the depth or level counter, which now reflects the minimum minutes taken for the desired conversion.

This BFS conceptualization ensures that the contamination wave propagates efficiently, and the counter provides the earliest minute each orange turns rotten. In instances where the matrix is initially free of fresh oranges or contains only isolated fresh oranges, the condition is quickly detected and handled appropriately, either by returning 0 or -1.

Solutions

  • Java
  • Python
java
class Solution {
    // Function to propagate rot process in the grid
    public boolean propagateRot(int currentMinute, int[][] orchard, int totalRows, int totalCols) {
        int[][] steps = { {-1, 0}, {0, 1}, {1, 0}, {0, -1}};
        boolean continueRotting = false;
        for (int r = 0; r < totalRows; ++r)
            for (int c = 0; c < totalCols; ++c)
                if (orchard[r][c] == currentMinute)
                    for (int[] move : steps) {
                        int newRow = r + move[0], newCol = c + move[1];
                        if (newRow >= 0 && newRow < totalRows && newCol >= 0 && newCol < totalCols)
                            if (orchard[newRow][newCol] == 1) {
                                orchard[newRow][newCol] = currentMinute + 1;
                                continueRotting = true;
                            }
                    }
        return continueRotting;
    }

    public int orangesRotting(int[][] grid) {
        int rows = grid.length, cols = grid[0].length;
        int minute = 2;
        while (propagateRot(minute, grid, rows, cols))
            minute++;

        for (int[] orchardRow : grid)
            for (int orangeState : orchardRow)
                if (orangeState == 1)
                    return -1;

        return minute - 2;
    }
}

The Rotting Oranges problem involves a grid where each cell can contain an orange that can be fresh, rotten, or empty. The goal is to determine the minimum number of minutes required for all fresh oranges to become rotten, given that a rotten orange at each minute turns its adjacent fresh oranges rotten.

The given solution in Java provides an efficient approach for solving this problem:

  1. Define the propagateRot function to simulate the rotting process for each minute:

    • Pass the current minute, orchard (grid), total rows, and total columns as parameters.
    • Use the steps array to represent possible movements: up, right, down, and left.
    • Iterate over each cell in the grid. If an orange turns rotten at the current minute, use the steps to try and rot adjacent oranges.
    • If any fresh orange rots during this process, set a flag to true, indicating that the process needs to continue into the next minute.
  2. Define the orangesRotting function to manage the propagation over multiple minutes and determine if all oranges can rot:

    • Initialize minute counters and dimensions of the grid.
    • Continuously call propagateRot while tracking each minute until no fresh oranges can be rotten.
    • After exiting the loop, recheck if any fresh oranges are still left, indicating that not all can be rotten.
    • Calculate the elapsed minutes since starting rotting (not counting the initial state and the first propagation minute passed).

By carefully managing the simulation of each minute and checking termination conditions, this solution efficiently determines how quickly all oranges can rot or if it's impossible, ensuring optimal time usage and clarity in processing the grid-based simulation.

python
class Solution:
    def rotOranges(self, matrix: List[List[int]]) -> int:
        max_rows, max_cols = len(matrix), len(matrix[0])

        moves = [(0, 1), (1, 0), (0, -1), (-1, 0)]

        def spreadRotten(current_time):
            continue_process = False
            for r in range(max_rows):
                for c in range(max_cols):
                    if matrix[r][c] == current_time:
                        for move in moves:
                            new_r, new_c = r + move[0], c + move[1]
                            if 0 <= new_r < max_rows and 0 <= new_c < max_cols:
                                if matrix[new_r][new_c] == 1:
                                    matrix[new_r][new_c] = current_time + 1
                                    continue_process = True
            return continue_process

        time_counter = 2
        while spreadRotten(time_counter):
            time_counter += 1

        for row in matrix:
            if 1 in row:
                return -1

        return time_counter - 2

The provided Python code defines a solution for the "Rotting Oranges" problem, where the goal is to find out the minimum number of minutes needed until all non-rotten oranges become rotten if it is possible at all.

Here's how the code works:

  • Read the matrix dimensions and define possible moves (right, down, left, up) using coordinate adjustments.
  • The spreadRotten function, when called with the current time, checks all elements in the matrix:
    • For each rotten orange (denoted by the current time in the time-stamped matrix), it tries to rot adjacent fresh oranges using the defined moves.
    • If a fresh orange is rotted, it updates its value to the current time plus one, marking the time at which it starts rotting.
    • It continues this process until no more fresh oranges can be rotted in a pass.
  • In the main part of the function, a time_counter starts at 2 (to account for the initial state as time 2 after the initial time 1 which is default for fresh oranges).
  • The loop keeps running the spreadRotten function and incrementing the time_counter until no more rotting occurs.
  • After rotting stops, the code checks if there are still fresh oranges left (denoted by 1 in the matrix). If any are found, it returns -1, indicating not all oranges can be rotted.
  • If all oranges have rotten successfully, the function returns the total time taken (time_counter - 2 to adjust for the initial start at 2) which represents minutes passed.

The approach leverages simulation with a time-stamped matrix and checks adjacency via coordinate manipulation. This ensures a comprehensive spread of the rot while efficiently tracking the process time. It returns either the total minutes required for all oranges to rot or -1 if it's impossible.

Comments

No comments yet.