你現在手裏有一份大小爲 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;
}
}