Given an n x ngrid containing only values 0 and 1, where 0 represents water and 1 represents land, find a water cell such that its distance to the nearest land cell is maximized, and return the distance. If no land or water exists in the grid, return -1.
The distance used in this problem is the Manhattan distance: the distance between two cells (x0, y0) and (x1, y1) is |x0 - x1| + |y0 - y1|.
The key idea is to treat all land cells as sources and perform a BFS to expand outwards, layer by layer. The first time a water cell is reached, its distance from land is recorded. The farthest water cell from any land will be the answer.
Add all land cells to a queue and mark them as visited.
For each cell in the queue, expand to its four neighbors (up, down, left, right) if they are water and unvisited, marking them as visited and adding them to the queue.
Track the distance as you expand each layer.
If there are no water or no land cells, return -1.
The answer is the last distance assigned to a water cell.
classSolution {
public:int maxDistance(vector<vector<int>>& grid) {
int n = grid.size(), ans =-1;
queue<pair<int, int>> q;
vector<vector<bool>> vis(n, vector<bool>(n));
for (int i =0; i < n; ++i)
for (int j =0; j < n; ++j)
if (grid[i][j] ==1) q.push({i, j}), vis[i][j] = true;
if (q.empty() || q.size() == n * n) return-1;
int dirs[4][2] = {{0,1},{1,0},{0,-1},{-1,0}};
while (!q.empty()) {
int sz = q.size();
++ans;
for (int k =0; k < sz; ++k) {
auto [i, j] = q.front(); q.pop();
for (auto& d : dirs) {
int x = i + d[0], y = j + d[1];
if (x >=0&& x < n && y >=0&& y < n &&!vis[x][y] && grid[x][y] ==0) {
vis[x][y] = true;
q.push({x, y});
}
}
}
}
return ans;
}
};
classSolution {
publicintmaxDistance(int[][] grid) {
int n = grid.length, ans =-1;
boolean[][] vis =newboolean[n][n];
Queue<int[]> q =new ArrayDeque<>();
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
if (grid[i][j]== 1) { q.add(newint[]{i, j}); vis[i][j]=true; }
if (q.isEmpty() || q.size() == n * n) return-1;
int[][] dirs = {{0,1},{1,0},{0,-1},{-1,0}};
while (!q.isEmpty()) {
int sz = q.size();
ans++;
for (int k = 0; k < sz; k++) {
int[] cur = q.poll();
for (int[] d : dirs) {
int x = cur[0]+ d[0], y = cur[1]+ d[1];
if (x >= 0 && x < n && y >= 0 && y < n &&!vis[x][y]&& grid[x][y]== 0) {
vis[x][y]=true;
q.add(newint[]{x, y});
}
}
}
}
return ans;
}
}
classSolution {
funmaxDistance(grid: Array<IntArray>): Int {
val n = grid.size
val vis = Array(n) { BooleanArray(n) }
val q = ArrayDeque<Pair<Int, Int>>()
for (i in0 until n)
for (j in0 until n)
if (grid[i][j] ==1) { q.add(i to j); vis[i][j] = true }
if (q.isEmpty() || q.size == n * n) return -1val dirs = arrayOf(0 to 1, 1 to 0, 0 to -1, -1 to 0)
var ans = -1while (q.isNotEmpty()) {
repeat(q.size) {
val(i, j) = q.removeFirst()
for ((dx, dy) in dirs) {
val x = i + dx; val y = j + dy
if (x in0 until n && y in0 until n && !vis[x][y] && grid[x][y] ==0) {
vis[x][y] = true q.add(x to y)
}
}
}
ans++ }
return ans
}
}
classSolution:
defmaxDistance(self, grid: list[list[int]]) -> int:
n = len(grid)
vis = [[False]*n for _ in range(n)]
q = [(i, j) for i in range(n) for j in range(n) if grid[i][j] ==1]
for i, j in q:
vis[i][j] =Trueifnot q or len(q) == n*n:
return-1 ans =-1while q:
nq = []
ans +=1for i, j in q:
for dx, dy in ((0,1),(1,0),(0,-1),(-1,0)):
x, y = i+dx, j+dy
if0<= x < n and0<= y < n andnot vis[x][y] and grid[x][y] ==0:
vis[x][y] =True nq.append((x, y))
q = nq
return ans
impl Solution {
pubfnmax_distance(grid: Vec<Vec<i32>>) -> i32 {
let n = grid.len();
letmut vis =vec![vec![false; n]; n];
letmut q =vec![];
for i in0..n {
for j in0..n {
if grid[i][j] ==1 {
q.push((i, j));
vis[i][j] =true;
}
}
}
if q.is_empty() || q.len() == n * n {
return-1;
}
let dirs = [(0,1),(1,0),(0,-1),(-1,0)];
letmut ans =-1;
while!q.is_empty() {
let sz = q.len();
ans +=1;
for _ in0..sz {
let (i, j) = q.remove(0);
for (dx, dy) in dirs.iter() {
let x = i asi32+ dx;
let y = j asi32+ dy;
if x >=0&& x < n asi32&& y >=0&& y < n asi32 {
let (x, y) = (x asusize, y asusize);
if!vis[x][y] && grid[x][y] ==0 {
vis[x][y] =true;
q.push((x, y));
}
}
}
}
}
ans
}
}