An interactive visualization of multi-source BFS. Watch how rot spreads simultaneously from all initially rotten oranges, level by level, one minute at a time.
BFS LeetCode 994 โ Mediumm x n grid where each cell has one of three values:
0 โ an empty cell1 โ a fresh orange2 โ a rotten orange-1.
fun orangesRotting(grid: Array<IntArray>): Int { val rows = grid.size; val cols = grid[0].size val queue = ArrayDeque<Pair<Int,Int>>() var fresh = 0 for (r in 0 until rows) // scan grid for (c in 0 until cols) if (grid[r][c] == 2) queue.add(r to c) else if (grid[r][c] == 1) fresh++ var minutes = 0 val dirs = listOf(0 to 1, 0 to -1, 1 to 0, -1 to 0) while (queue.isNotEmpty() && fresh > 0) { repeat(queue.size) { val (r, c) = queue.removeFirst() for ((dr, dc) in dirs) { val nr = r+dr; val nc = c+dc if (nr in 0 until rows && nc in 0 until cols && grid[nr][nc]==1) { grid[nr][nc] = 2 fresh-- queue.add(nr to nc) } } }; minutes++ } return if (fresh > 0) -1 else minutes
This is a classic multi-source BFS problem. Instead of starting BFS from a single node, we enqueue all initially rotten oranges at once. Each BFS level represents one minute of time passing, during which all currently rotten oranges spread rot to their fresh neighbors simultaneously.
fresh > 0, return -1 (impossible). Otherwise, return minutes.By starting with all rotten oranges in the queue at "time 0", the BFS naturally simulates the simultaneous spread of rot. Each level of the BFS corresponds to exactly one minute. This is equivalent to adding a virtual "super source" node connected to all initial rotten oranges, then running standard BFS.
Every cell is visited at most once during BFS, giving O(m*n) time. The queue can hold at most all cells in the worst case, so space is O(m*n).