Rotting Oranges
Reported by candidates from Salesforce's online assessment. Pattern, common pitfall, and the honest play if you blank under the timer.
Salesforce reported this one in September 2026, and under the orange theme it's a plain multi-source shortest-path problem on a grid. If the OA invite is sitting in your inbox, the whole question comes down to one idea: spread from every rotten orange at the same time and count the layers. That's breadth-first search with all the starting points loaded into the queue up front. The grid goes up to 500 by 500, so a sloppy approach will hurt. Nothing about it is exotic, but the edge cases (no fresh oranges, unreachable ones) are where people lose points. StealthCoder is the backup if your mind goes blank mid-assessment.
The problem
You are given a rectangular grid whose cells contain 0 for empty, 1 for a fresh orange, or 2 for a rotten orange. For this exercise, assume every minute each fresh orange orthogonally adjacent to a rotten orange becomes rotten, and all changes in one minute happen simultaneously. Return the minimum minutes until no fresh orange remains. Return -1 if that is impossible. Return 0 when no fresh orange exists initially. Function orangesRotting(grid: int[][]) → int Examples Example 1 grid = [[2,1,1],[1,1,0],[0,1,1]] return = 4 The final fresh orange is reached by the fourth simultaneous breadth-first layer. Example 2 grid = [[2,1,1],[0,1,1],[1,0,1]] return = -1 The lower-left fresh orange is disconnected from every rotten orange. Example 3 grid = [[0,2]] return = 0 No fresh orange exists. Constraints 1 <= grid.length <= 500. 1 <= grid[row].length <= 500. Every row has the same length. Each cell is 0, 1, or 2.
Reported by candidates. Source: FastPrep
Pattern and pitfall
The trick is multi-source BFS. Scan the grid once, push every rotten cell into a queue, and count the fresh ones. Then process the queue level by level. Each level is one minute. When a fresh neighbor turns rotten, decrement the fresh counter and enqueue it. The pitfall is the minute count. If you increment per cell instead of per level, your answer is way too big. Also don't increment after the last level that adds nothing, or you're off by one. At the end, if fresh is still above zero, return -1. If fresh was zero at the start, return 0 before the loop. Mutate the grid in place to mark visited, so you skip a separate set. Time is O(rows times cols). If you freeze on the level-counting logic during the live OA, StealthCoder is the safety net that shows you the clean version.
StealthCoder is the hedge for the one pattern you didn't drill. It runs invisibly during the screen share.
You can drill Rotting Oranges cold, or you can hedge it. StealthCoder runs invisibly during screen share and surfaces a working solution in under 2 seconds. The proctor sees the IDE. They don't see what's behind it. If you're reading this with an OA window open, you're who this was built for.
Get StealthCoderRelated leaked OAs
This OA pattern shows up on LeetCode as rotting oranges. If you have time before the OA, drill that.
You've seen the question.
Make sure you actually pass Salesforce's OA.
Salesforce reuses patterns across OAs. If you're reading this with an OA window open, you're who this was built for. Works on HackerRank, CodeSignal, CoderPad, and Karat.
Rotting Oranges FAQ
How hard is Rotting Oranges really?+
Medium. The code is short once you see it's BFS. Most failures come from the minute counter and the no-fresh-oranges edge case, not from the algorithm. If you've written a grid BFS before, this takes maybe 15 minutes.
What's the trick for the Salesforce version?+
Start BFS from all rotten oranges at once, not one at a time. Process the queue in level-sized chunks so each chunk equals one minute. Track a fresh count so you can detect the -1 case without rescanning the grid.
Why not simulate minute by minute with nested loops?+
You can, but each pass scans the whole grid and there can be up to about 250,000 cells with long chains. That's far slower than BFS, which touches each cell once. Simulation is a bad fit for the 500 by 500 constraint.
What edge cases should I test?+
Test a grid with no fresh oranges (return 0), one with no rotten oranges but some fresh (return -1), a fresh orange walled off by zeros (return -1), and a single-cell grid. Example 3, [[0,2]], covers the zero case.
How do I prepare in 48 hours?+
Write multi-source BFS on a grid from scratch twice. Practice the level-by-level loop and in-place visited marking. Then try a couple of grid BFS variants. That's enough, since this pattern repeats across many grid questions.