Practice LeetCode 994 · Rotting Oranges · GFG · Rotten Oranges
Graphs BFS Multi-source Grid

Breadth-First Search · Rotting Oranges

Rot spreads outward one layer per minute from every rotten orange at once. That "expand by layers" behavior is exactly what BFS does, run from many sources simultaneously.

The idea

Each grid cell is a node; 4-directional neighbors are edges. BFS visits nodes in waves: everything at distance 1 before anything at distance 2. Here one wave = one minute of rot spreading.

Seed the queue with all rotten oranges up front (that's the "multi-source" trick), then expand level by level.

The rules

  • 2 = rotten, 1 = fresh, 0 = empty
  • Every minute, a rotten orange rots its 4 fresh neighbors
  • Answer = minutes until no fresh orange remains
  • If a fresh orange is unreachable, return -1

Step through the rot

slow fast
Step 0
Minute
0
Fresh left
0
Rotten
0
Queue size
0

C++

int orangesRotting(vector<vector<int>>& grid) {
    int rows = grid.size(), cols = grid[0].size();
    queue<pair<int,int>> q;
    int fresh = 0;

    // seed queue with every rotten orange (multi-source)
    for (int r = 0; r < rows; r++)
        for (int c = 0; c < cols; c++) {
            if (grid[r][c] == 2) q.push({r, c});
            else if (grid[r][c] == 1) fresh++;
        }

    int minutes = 0;
    int dr[] = {-1,1,0,0}, dc[] = {0,0,-1,1};

    while (!q.empty() && fresh > 0) {
        int sz = q.size();
        while (sz--) {                // process one full layer
            auto [r, c] = q.front(); q.pop();
            for (int d = 0; d < 4; d++) {
                int nr = r + dr[d], nc = c + dc[d];
                if (nr < 0 || nc < 0 || nr >= rows || nc >= cols) continue;
                if (grid[nr][nc] != 1) continue;
                grid[nr][nc] = 2;      // rot it
                fresh--;
                q.push({nr, nc});
            }
        }
        minutes++;
    }
    return fresh == 0 ? minutes : -1;
}
Time
O(R × C)

Every cell is enqueued and dequeued at most once, and each has 4 neighbor checks.

Space
O(R × C)

Worst case the queue holds every cell (all oranges rotten at once).

Layers
= answer

Number of BFS levels equals the minutes returned. Level order is what makes BFS give shortest distance.

  • Multi-source BFS is just BFS seeded with more than one starting node. No extra machinery needed, push them all before the loop.
  • The sz = q.size() snapshot is the key to counting layers. Freeze the size, drain exactly that many, then bump the minute counter.
  • Track fresh count instead of re-scanning the grid. If it hits 0 you're done; if the queue empties first, something's unreachable → return -1.
  • Mutating the grid to 2 doubles as your visited marker, so no separate visited set.
  • Same layer-by-layer pattern powers word ladder, shortest path in unweighted grids, and 0-1 matrix distance.