Given an N x N grid
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.
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|
.
If no land or water exists in the grid, return -1
.
Example 1:
Input: [[1,0,1],[0,0,0],[1,0,1]]
Output: 2
Explanation:
The cell (1, 1) is as far as possible from all the land with distance 2.
Example 2:
Input: [[1,0,0],[0,0,0],[0,0,0]]
Output: 4
Explanation:
The cell (2, 2) is as far as possible from all the land with distance 4.
Note:
1 <= grid.length == grid[0].length <= 100
grid[i][j]
is0
or1
Java代码
class Solution {
private static final int WATER = 0;
private static final int LAND = 1;
private static final int[][] dirs = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
public int maxDistance(int[][] grid) {
int n = grid.length;
Queue<int[]> queue = new LinkedList<>();
// 将所有陆地入Queue
for (int r = 0; r < n; ++r) {
for (int c = 0; c < n; ++c) {
if (grid[r][c] == LAND) {
queue.offer(new int[]{r, c});
}
}
}
if (queue.isEmpty() || queue.size() == n * n) {
// 无陆地或者无海洋
return -1;
}
// 当前格子,声明在while外面是为了保存最后一次出Queue的格子
int[] cur = null;
while (!queue.isEmpty()) {
cur = queue.poll();
for (int[] dir : dirs) {
int r = cur[0] + dir[0];
int c = cur[1] + dir[1];
if (r < 0 || r >= n || c < 0 || c >= n) {
continue;
}
if (grid[r][c] == WATER) {
// [r, c]和当前位置相比距离加1
grid[r][c] = grid[cur[0]][cur[1]] + 1;
queue.offer(new int[]{r, c});
}
}
}
// 由于陆地本身是1,所以最后距离要减1
return grid[cur[0]][cur[1]] - LAND;
}
}