Opening the reading…
Opening the reading…
GRAPHS › DFS AND BFS ON GRAPHS
Open — the attempt gate is not wired up yet
This editorial is meant to unlock after you have run the problem at least once, with the worked solution behind one further deliberate click. That needs per-learner unlock state nothing stores today, so for now the whole article is open.
Try it yourself first →For one water cell, the answer is its distance to the nearest land, not its distance to a particular land cell. If you start a search from that water cell, the first land you encounter gives its nearest-land distance, but repeating that search for every water cell wastes work and repeats the same paths.
Reverse the search. Put every land cell into one BFS queue at distance 0 and let all of them expand together. BFS reaches a cell through the shortest number of four-direction moves, and the first wave to reach a water cell must come from its nearest land. Therefore, the furthest water cell is the last water cell reached, or equivalently the one with the largest assigned distance.
| MEASURE | BOUND | WHY |
|---|---|---|
| Time | O(n^2) | Each cell enters the queue at most once, and each removal checks exactly four directions. The constant four does not grow with n, so the total work counts a constant amount per one of the n^2 cells. |
| Space | O(n^2) extra | The distance grid stores one value for every cell, and the queue can contain a whole frontier; in the worst input shape both are proportional to n^2. The returned distance is a scalar output, so it is not counted as working memory. |
#include <vector>
#include <queue>
#include <utility>
using namespace std;
class Solution {
public:
int maxDistance(vector<vector<int>>& grid) {
int n = grid.size();
if (n == 0) return -1;
vector<vector<int>> dist(n, vector<int>(n, -1));
queue<pair<int, int>> q;
for (int r = 0; r < n; ++r) {
for (int c = 0; c < n; ++c) {
if (grid[r][c] == 1) {
dist[r][c] = 0;
q.push({r, c});
}
}
}
if (q.empty() || static_cast<int>(q.size()) == n * n) {
return -1;
}
int directions[4][2] = {
{-1, 0}, {1, 0}, {0, -1}, {0, 1}
};
int best = 0;
while (!q.empty()) {
auto [r, c] = q.front();
q.pop();
for (auto& direction : directions) {
int nr = r + direction[0];
int nc = c + direction[1];
if (nr < 0 || nr >= n || nc < 0 || nc >= n) {
continue;
}
if (dist[nr][nc] != -1) {
continue;
}
dist[nr][nc] = dist[r][c] + 1;
best = max(best, dist[nr][nc]);
q.push({nr, nc});
}
}
return best;
}
};The distance grid serves two roles: it records the answer for each cell and marks whether that cell has already entered the BFS. Checking dist[nr][nc] != -1 prevents a cell from being enqueued again. That single guard is what preserves both the shortest-distance guarantee and the linear visit count.