FAANGPrep Sprint
Rotting Oranges
Spread rot from every source at once, one queue pass per minute, and decide with the fresh count.
Examples
The last orange to turn is (2, 2), at minute 4.
The orange at (2, 0) has only empty cells beside it, so it never rots.
Nothing is fresh, so no minutes pass.
Problem Understanding
A grid holds three kinds of cell: 0 is empty, 1 is a fresh orange and 2 is a rotten one. Every minute, each rotten orange rots the fresh oranges directly above, below, left and right of it — diagonals do not count.
- Goal: the minutes until nothing fresh is left, or
-1if that never happens (LeetCode 994). - Input:
[[2,1,1],[1,1,0],[0,1,1]]. Output:4. - Input:
[[2,1,1],[0,1,1],[1,0,1]]. Output:-1— the orange at(2, 0)has only empty cells beside it. - Input:
[[0,2]]. Output:0— nothing is fresh, so no time has to pass.
Every rotten orange spreads during the same minute, which is what makes this a multi-source BFS rather than a search from one starting point.
Algorithm Strategy
One scan to set up, then one pass of the queue per minute.
- Scan once. Put every rotten orange in the queue and count the fresh ones. Both facts come out of the same pass.
- Answer the easy case. No fresh oranges means no time has to pass: return 0 before the loop.
- One minute per pass. Read the queue's size, then dequeue exactly that many oranges. Those are the ones that were rotten when the minute began, so everything they rot turns at the same time.
- Rot the neighbours. For each of the four directions, a cell that is on the grid and still
1becomes2, decreases the fresh count, and joins the queue for the next minute. - Decide. When the queue drains,
fresh == 0means the answer is the minute count; anything left fresh could never be reached, so the answer is-1.
Why the fresh count and not the grid. Checking "is anything still fresh" by rescanning the grid each minute would make the method quadratic in the cell count. One integer, decremented as each orange turns, answers the same question in O(1).
Interactive Visualization
2 = ROTTEN · 1 = FRESH · 0 = EMPTY · mN = THE MINUTE A CELL TURNED
SCAN THE GRID
minutes
0
fresh left
0
Answer
—
queue (front first)
(0, 0) is rotten already — it starts in the queue, so every source spreads from minute 1
Next
(0, 1) is fresh — fresh = 1
grid
The opening scan is stepped through cell by cell, because that is where both the queue and the fresh count come from. Then each minute is one pass: every orange that was rotten when the minute began is dequeued, and the ones it rots are stamped with the minute they turned. Try Two sources, where rot spreads from both corners at once and the middle turns sooner than either could manage alone.
