当前位置: 代码迷 >> 综合 >> leedcode:地图分析
  详细解决方案

leedcode:地图分析

热度:78   发布时间:2023-11-19 18:10:55.0

3.29日:地图分析

你现在手里有一份大小为 N x N 的『地图』(网格) grid,上面的每个『区域』(单元格)都用 0 和 1 标记好了。其中 0 代表海洋,1 代表陆地,你知道距离陆地区域最远的海洋区域是是哪一个吗?请返回该海洋区域到离它最近的陆地区域的距离。

我们这里说的距离是『曼哈顿距离』( Manhattan Distance):(x0, y0) 和 (x1, y1) 这两个区域之间的距离是 |x0 - x1| + |y0 - y1| 。如果我们的地图上只有陆地或者海洋,请返回 -1。

可以通过下图理解单源和多源广度优先搜索

分析:这道题很明显要用BFS(广度优先遍历)算法,实际上是求海洋格子到陆地格子的最长距离。

1、一开始,找出所有陆地格子,放入队列中,作为第0层的节点

2、然后进行BFS遍历,每个节点的相邻节点可能是上、下、左、右四个方向的节点

3、当遍历结束,当前的遍历层数就是海洋格子到陆地格子的最长距离

注意:为了在遍历中不重复访问海洋格子,我们将已经遍历过的海洋格子的值改为 2,和原来海洋格子里的 0 区别开来。

public int maxDistance(int[][] grid) {
    int N = grid.length;Queue<int[]> queue = new ArrayDeque<>();// 将所有的陆地格子加入队列for (int i = 0; i < N; i++) {
    for (int j = 0; j < N; j++) {
    if (grid[i][j] == 1) {
    queue.add(new int[]{
    i, j});}}}// 如果我们的地图上只有陆地或者海洋,请返回 -1。if (queue.isEmpty() || queue.size() == N * N) {
    return -1;}int distance = -1;while (!queue.isEmpty()) {
    distance++;int n = queue.size();// 这里一口气取出 n 个结点,以实现层序遍历for (int i = 0; i < n; i++) {
    int[] cell = queue.poll();int r = cell[0];int c = cell[1];// 遍历上方单元格if (r-1 >= 0 && grid[r-1][c] == 0) {
    grid[r-1][c] = 2;queue.add(new int[]{
    r-1, c});}// 遍历下方单元格if (r+1 < N && grid[r+1][c] == 0) {
    grid[r+1][c] = 2;queue.add(new int[]{
    r+1, c});}// 遍历左边单元格if (c-1 >= 0 && grid[r][c-1] == 0) {
    grid[r][c-1] = 2;queue.add(new int[]{
    r, c-1});}// 遍历右边单元格if (c+1 < N && grid[r][c+1] == 0) {
    grid[r][c+1] = 2;queue.add(new int[]{
    r, c+1});}}}return distance;
}