你现在手里有一份大小为 N x N 的『地图』(网格) grid,上面的每个『区域』(单元格)都用 0 和 1 标记好了。其中 0 代表海洋,1 代表陆地,你知道距离陆地区域最远的海洋区域是是哪一个吗?请返回该海洋区域到离它最近的陆地区域的距离。
我们这里说的距离是『曼哈顿距离』( Manhattan Distance):(x0, y0) 和 (x1, y1) 这两个区域之间的距离是 |x0 - x1| + |y0 - y1| 。
如果我们的地图上只有陆地或者海洋,请返回 -1。
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.
示例 1:
输入:[[1,0,1],[0,0,0],[1,0,1]]
输出:2
解释:
海洋区域 (1, 1) 和所有陆地区域之间的距离都达到最大,最大距离为 2。
思路
(1)参见:广度优先遍历(Java)——by liweiwei1419
(2)图的多源BFS
解法-bug
class Solution {
public int maxDistance(int[][] grid) {
int[][] directions = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
int len = grid.length;
Queue<Integer> queue = new LinkedList<>();
for(int i = 0; i < len; i++){
for(int j = 0; j < len; j++){
if(grid[i][j] == 1){
int index = i * len + j;
queue.offer(index);
}
}
}
int size = queue.size();
if(size==0 || size == len*len){
return -1;
}
int count = 0;
while(!queue.isEmpty()){
int curSize = queue.size();
for(int i = 0; i < curSize; i++){
int index = queue.poll();
int x = index % len;
int y = index / len;
for (int[] direction : directions) {
int newX = x + direction[0];
int newY = y + direction[1];
// 只关心有效范围内的海洋(0)
if (inArea(newX, newY, len) && grid[newX][newY] == 0) {
grid[newX][newY] = 1;
queue.offer(newX * len + newY);
}
}
}
count++;
}
return count-1;
}
private boolean inArea(int x, int y, int N) {
return 0 <= x && x < N && 0 <= y && y < N;
}
}