Islands and Treasure (Walls and Gates)
Multi-source BFS: seed the queue with every treasure cell at once instead of a single start node, and let a 'drain the current level, then bump distance' loop stand in for the `[node, distance]` tuples `shortestPath` used for the exact same job.
The problem
Implement `islandsAndTreasure(grid)`, mutating an `m x n` grid in place. Each cell is one of: `0` (a treasure chest), `-1` (a wall, impassable), or `2147483647` (empty land). Fill every empty cell with the distance to its nearest chest, leaving walls untouched.
'Nearest' is over every chest at once, not just one, so a single BFS from one starting cell isn't enough — the search has to start from all of them simultaneously, so whichever chest's search reaches a given empty cell first is guaranteed to be the nearest.
The approach
Multi-source BFS seeds the queue with the coordinates of *every* `0` cell in one pass over the grid, marking each visited immediately. That's the only structural change from a single-source search: instead of `q = [source]`, it's `q = [...every treasure]` — the traversal after that point doesn't know or care how many sources it started from.
Distance isn't carried per-entry the way `shortestPath` carried `[node, distanceFromSource]`. Instead the outer `while` loop processes one full BFS 'level' at a time: `size = q.length` snapshots how many cells belong to the current distance, an inner `while (size > 0)` drains exactly that many off the front, and `distance` increments once per level rather than once per node. Every cell popped inside that inner loop is exactly `distance` steps from its nearest chest, so `grid[cr][cc] = distance` writes the answer the instant a cell is dequeued.
The neighbour check only enqueues cells still holding the sentinel `2147483647` — a wall (`-1`) or an already-filled cell just fails that comparison and gets skipped, so walls stay untouched and nothing is visited twice.
The solution
class Solution {
/**
* @param {number[][]} grid
*/
islandsAndTreasure(grid) {
const visited = new Set()
const q = []
// Pushing all the treasure cells as BFS sources
for (let r = 0; r < grid.length; r++) {
for (let c = 0; c < grid[0].length; c++) {
if (grid[r][c] === 0) {
q.push([r, c])
visited.add(`${r},${c}`)
}
}
}
const directions = [[1, 0], [-1, 0], [0, 1], [0, -1]]
let distance = 0
while (q.length) {
let size = q.length
while (size > 0) {
const [cr, cc] = q.shift()
grid[cr][cc] = distance
for (let [dr, dc] of directions) {
const [nr, nc] = [cr + dr, cc + dc]
const nColInbound = nc >= 0 && nc < grid[0].length
const nRowInbound = nr >= 0 && nr < grid.length
const inBound = nColInbound && nRowInbound
const neighborPos = `${nr},${nc}`
if (inBound && grid[nr][nc] === 2147483647 && !visited.has(neighborPos)) {
visited.add(neighborPos)
q.push([nr, nc])
}
}
size--
}
distance++
}
}
}Time O(R * C)Space O(R * C)