題目描述
你現在手裏有一份大小爲 N x N 的『地圖』(網格) grid,上面的每個『區域』(單元格)都用 0 和 1 標記好了。其中 0 代表海洋,1 代表陸地,你知道距離陸地區域最遠的海洋區域是是哪一個嗎?請返回該海洋區域到離它最近的陸地區域的距離。
我們這裏說的距離是『曼哈頓距離』( Manhattan Distance):(x0, y0) 和 (x1, y1) 這兩個區域之間的距離是 |x0 - x1| + |y0 - y1| 。
如果我們的地圖上只有陸地或者海洋,請返回 -1。
思路分析
BFS
樹的BFS就是層序遍歷,圖的BFS區別在
- 源點可能多個,先把多個源點入隊;
- 無向圖必須標誌訪問,用memo或者直接原地修改數組。
本題就是多源點的BFS,把所有的陸地看成一個整體,從各個陸地開始同時向外一層一層的擴散,最後擴散到的海洋就是最遠的海洋。
其實多源點BFS可以看成是單源點BFS的第二層。有一個超級源點連接着多源點,我們用隊列實現。
代碼實現
public int maxDistance(int[][] grid) {
int[] dx={0,0,1,-1};
int[] dy={1,-1,0,0};
Queue<int[]> queue=new ArrayDeque<>();
int n=grid.length;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(grid[i][j]==1){
queue.offer(new int[]{i,j});
}
}
}
boolean hasOcean=false;
int[] point =null;
while(!queue.isEmpty()){
point=queue.poll();
int x= point[0];
int y= point[1];
for(int i=0;i<4;i++){
int newX=x+dx[i];
int newY=y+dy[i];
if(newX<0||newX>=n||newY<0||newY>=n||grid[newX][newY]!=0){
continue;
}
grid[newX][newY]=grid[x][y]+1;
hasOcean=true;
queue.offer(new int[]{newX,newY});
}
}
if(point == null || !hasOcean){
return -1;
}
return grid[point[0]][point[1]]-1;
}