02
Multi-source BFS (Graph BFS / DFS Sub-pattern)
Many cells spread at the same speed; find each cell's distance to the nearest source (or when the spread ends).
Signals in the problem statement
- ›
"every minute, each … spreads to its neighbours"
- ›
"distance to the nearest 0 / gate / water"
- ›
"minimum time until all …"
What makes it different
Rotting Oranges is the template: all rotten oranges start in the queue, and one BFS level is one minute; any fresh orange left at the end means -1. 01 Matrix and Walls and Gates start from the targets (the 0s, the gates), not from the cells asking the question. Map of Highest Peak is the same BFS with water as the sources; the distance is the height.
Questions
ordered from “learn the idea” to “recognise it without help”- 1Rotting OrangesWalkthroughMediumBasic Anchor·LeetCode #994
- 201 MatrixWalkthroughMediumBasic Reinforcement·LeetCode #542
- 3Walls and GatesWalkthroughMediumSlight Variation·LeetCode #286 Premium
- 4Map of Highest PeakWalkthroughMediumMedium·LeetCode #1765
Template
multi-source-bfs-template.cpp
// Multi-source BFS: every source goes in the queue at distance 0, then all spread together.
vector<vector<int>> nearestSource(const vector<vector<int>>& grid) { // 1 = source, 0 = open, -1 = wall
int R = grid.size(), C = grid[0].size();
vector<vector<int>> dist(R, vector<int>(C, -1)); // -1 = not reached yet
queue<pair<int, int>> q;
for (int r = 0; r < R; r++)
for (int c = 0; c < C; c++)
if (grid[r][c] == 1) { dist[r][c] = 0; q.push({r, c}); }
int dr[4] = {1, -1, 0, 0}, dc[4] = {0, 0, 1, -1};
while (!q.empty()) {
auto [r, c] = q.front(); q.pop();
for (int d = 0; d < 4; d++) {
int nr = r + dr[d], nc = c + dc[d];
if (nr < 0 || nc < 0 || nr >= R || nc >= C || grid[nr][nc] == -1 || dist[nr][nc] != -1) continue;
dist[nr][nc] = dist[r][c] + 1; // first time reached = nearest source
q.push({nr, nc});
}
}
return dist;
}Remember this · Graph BFS / DFS
Trigger
Grid of cells, islands, regions, "minimum steps", transformations between states, connected components.
Think
What is a node, what is an edge, and do I need the shortest path or just reachability?
Key question
How do I mark visited so I never process a node twice?