AlgoMaster Logo

Rotting Oranges

mediumFrequency5 min readUpdated June 23, 2026

Understanding the Problem

We have a grid of oranges. Rotten oranges spread rot to their fresh neighbors every minute, all at the same time. We need to find how many minutes it takes for every fresh orange to become rotten, or determine that some fresh oranges can never be reached.

The spreading is simultaneous. All rotten oranges infect their neighbors during the same minute, not one orange finishing its spread before another begins. That parallel, level-by-level expansion is what makes this a BFS problem rather than a DFS problem, since BFS expands outward one ring at a time and each ring maps to one minute.

The -1 case covers fresh oranges that are cut off from every rotten orange by empty cells. Such an orange can never rot, so we return -1.

Key Constraints:

  • 1 <= m, n <= 10 -> The grid is at most 10x10 = 100 cells, so even an O((m*n)^2) brute force passes. That headroom lets us start with a direct simulation before optimizing to BFS.
  • grid[i][j] is 0, 1, or 2 -> Three possible values, so we can overwrite a cell to 2 as a visited marker without losing information.

Approach 1: Brute Force Simulation

Intuition

Simulate exactly what the problem describes. Each minute, scan the entire grid and find every fresh orange adjacent to a rotten orange. Mark those fresh oranges as rotten. Repeat until nothing changes. Count the minutes.

The order of updates matters. If we rot an orange and then immediately use it to rot its neighbors in the same scan, rot spreads more than one ring in a single minute, which overcounts how fast it travels. To prevent that, we record which cells should rot during the scan but apply all the updates only after the scan finishes. This separates oranges that were rotten at the start of the minute from oranges that became rotten this minute.

Algorithm

  1. Count all fresh oranges in the grid.
  2. Initialize minutes = 0.
  3. In each round, scan the entire grid. For each fresh orange adjacent to a rotten orange, mark it for rotting.
  4. After the full scan, apply all the rotting marks. Decrement the fresh count for each newly rotten orange.
  5. If any oranges rotted this round, increment minutes and repeat. If none rotted, stop.
  6. If fresh oranges remain, return -1. Otherwise, return minutes.

Example Walkthrough

1Initial grid: 2=rotten, 1=fresh, 0=empty. fresh=6
0
1
2
0
rotten
2
1
1
1
1
1
0
2
0
1
1
1/5

Code

This rescans the whole grid every minute, even cells that rotted long ago. The next approach tracks only the newly rotten oranges and processes each cell once.

Approach 2: Multi-source BFS

Intuition

Rot spreading from multiple sources at once is what multi-source BFS models. Instead of running BFS from a single starting point, we load all initial rotten oranges into the queue before the search begins. BFS then processes them level by level, and each level corresponds to one minute of elapsed time.

This is like dropping several pebbles into a pond at the same instant. Each pebble starts its own ripple, and the ripples expand outward together. The queue produces the same effect: all initial rotten oranges go in first (level 0), then their fresh neighbors become rotten (level 1), then those neighbors' fresh neighbors (level 2), and so on.

We also keep a count of fresh oranges and decrement it each time one rots during the search. When the queue empties, any remaining fresh oranges were never reached, so we return -1.

Algorithm

  1. Scan the grid. Add all rotten oranges to a queue. Count all fresh oranges.
  2. If there are no fresh oranges, return 0 immediately.
  3. Run BFS. For each level (minute), process all oranges currently in the queue.
  4. For each rotten orange, check its 4 neighbors. If a neighbor is fresh, mark it rotten, decrement the fresh count, and add it to the queue.
  5. After processing a full level, increment the minute counter, but only when that level rotted at least one orange.
  6. When the queue is empty, check: if fresh == 0, return minutes. Otherwise, return -1.

Example Walkthrough

1Initial: seed queue with all rotten oranges. Queue=[(0,0)], fresh=6
0
1
2
0
queue
2
1
1
1
1
1
0
2
0
1
1
1/6

Code