📜  最近的一对岛屿之间的距离

📅  最后修改于: 2022-05-13 01:56:14.613000             🧑  作者: Mango

最近的一对岛屿之间的距离

给定一个包含0s 和 1sgrid[][] ,其中“0”代表水, “1”代表土地。假设一个岛屿是一组四面被水(0s)包围的土地(1s)。

任务是找到两个最近的岛屿之间的距离,使得:

  • 两个岛之间的距离是两个岛之间的最小“0”数。
  • 只允许 4 个方向移动。
  • 网格中至少存在 2 个岛屿。

例子:

天真的方法:

要找到 2 个岛屿之间的最小距离,请按照以下步骤操作:

  • 将每个岛屿的坐标分别存储在 List/vector 中。
    • 创建一个布尔访问数组来标记元素是否已被访问。
    • 遍历网格,如果一个元素为'1'且未访问,则调用dfs获取对应岛的所有元素
    • 将该岛的坐标存储在列表中。
  • 找到列表中每对岛屿之间的最小距离。
    • 对于列表中的每一对岛屿,找到它们之间的最小距离。
      • 2 个岛之间的距离将是两个岛中每对点之间的最小距离。
  • 返回岛屿之间所有距离的最小值。

下面是实现方法的代码:

Java
// Java code to implement the approach
import java.util.*;
 
class GFG {
    static int row;
    static int col;
 
    // A class to represent coordinates of
    // element in matrix
    static class Pair {
        int x;
        int y;
        Pair(int x, int y)
        {
            this.x = x;
            this.y = y;
        }
    }
 
    // Function to find closest distance
    static void closestDistance(int[][] grid)
    {
        row = grid.length;
        col = grid[0].length;
 
        // List of coordinates
        // of all the islands
        ArrayList > list
            = findIslands(grid);
 
        // Number of islands
        int n = list.size();
 
        // Variable to store
        // minimum of all distances
        int ans = Integer.MAX_VALUE;
        for (int i = 0; i < n - 1; i++) {
            for (int j = i + 1; j < n; j++) {
                ArrayList island1
                    = list.get(i);
                ArrayList island2
                    = list.get(j);
                int dist = findDistance(island1,
                                        island2);
                ans = Math.min(dist, ans);
            }
        }
        System.out.println(ans);
    }
 
    // Function to find and
    // store all islands in list
    static ArrayList >
    findIslands(int[][] grid)
    {
 
        boolean[][] visited
            = new boolean[row][col];
        ArrayList > list
            = new ArrayList<>();
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                if (grid[i][j] == 1
                    && !visited[i][j]) {
                    ArrayList island
                        = new ArrayList<>();
                    dfs(visited, grid, i,
                        j, island);
                    list.add(island);
                }
            }
        }
        return list;
    }
 
    // Function to find min distance
    // between 2 islands
    static int findDistance(ArrayList island1,
                            ArrayList island2)
    {
        int dist = Integer.MAX_VALUE;
        for (int i = 0; i < island1.size();
             i++) {
            Pair point1 = island1.get(i);
            for (int j = 0; j < island2.size();
                 j++) {
                Pair point2 = island2.get(j);
                int distp1p2
                    = Math.abs(point1.x - point2.x)
                      + Math.abs(point1.y - point2.y)
                      - 1;
                dist = Math.min(dist, distp1p2);
            }
        }
        return dist;
    }
 
    static int[] dirx = { 0, 1, 0, -1 };
    static int[] diry = { 1, 0, -1, 0 };
 
    static void dfs(boolean[][] visited,
                    int[][] grid,
                    int i, int j,
                    ArrayList island)
    {
        visited[i][j] = true;
        island.add(new Pair(i, j));
        for (int idx = 0; idx < 4; idx++) {
            int x = i + dirx[idx];
            int y = j + diry[idx];
            if (isValid(x, y)
                && grid[x][y] == 1
                && !visited[x][y]) {
                dfs(visited, grid, x, y, island);
            }
        }
    }
 
    // Function to check if
    // a point is inside grid
    static boolean isValid(int x, int y)
    {
        if (x < 0 || x >= row
            || y < 0 || y >= col)
            return false;
        return true;
    }
 
    // Driver code
    public static void main(String[] args)
    {
        int[][] grid = { { 1, 0, 0, 0, 1 },
                         { 1, 1, 0, 0, 0 },
                         { 0, 0, 0, 0, 0 },
                         { 0, 0, 1, 1, 1 } };
        closestDistance(grid);
    }
}


C#
// C# code to implement the approach
using System;
using System.Collections.Generic;
 
public class GFG {
  static int row;
  static int col;
 
  // A class to represent coordinates of
  // element in matrix
  class Pair {
    public int x;
    public int y;
    public Pair(int x, int y)
    {
      this.x = x;
      this.y = y;
    }
  }
 
  // Function to find closest distance
  static void closestDistance(int[,] grid)
  {
    row = grid.GetLength(0);
    col = grid.GetLength(1);
 
    // List of coordinates
    // of all the islands
    List > list
      = findIslands(grid);
 
    // Number of islands
    int n = list.Count;
 
    // Variable to store
    // minimum of all distances
    int ans = int.MaxValue;
    for (int i = 0; i < n - 1; i++) {
      for (int j = i + 1; j < n; j++) {
        List island1
          = list[i];
        List island2
          = list[j];
        int dist = findDistance(island1,
                                island2);
        ans = Math.Min(dist, ans);
      }
    }
    Console.WriteLine(ans);
  }
 
  // Function to find and
  // store all islands in list
  static List >
    findIslands(int[,] grid)
  {
 
    bool[,] visited
      = new bool[row,col];
    List > list
      = new List>();
    for (int i = 0; i < row; i++) {
      for (int j = 0; j < col; j++) {
        if (grid[i,j] == 1
            && !visited[i,j]) {
          List island
            = new List();
          dfs(visited, grid, i,
              j, island);
          list.Add(island);
        }
      }
    }
    return list;
  }
 
  // Function to find min distance
  // between 2 islands
  static int findDistance(List island1,
                          List island2)
  {
    int dist = int.MaxValue;
    for (int i = 0; i < island1.Count;
         i++) {
      Pair point1 = island1[i];
      for (int j = 0; j < island2.Count;
           j++) {
        Pair point2 = island2[j];
        int distp1p2
          = Math.Abs(point1.x - point2.x)
          + Math.Abs(point1.y - point2.y)
          - 1;
        dist = Math.Min(dist, distp1p2);
      }
    }
    return dist;
  }
 
  static int[] dirx = { 0, 1, 0, -1 };
  static int[] diry = { 1, 0, -1, 0 };
 
  static void dfs(bool[,] visited,
                  int[,] grid,
                  int i, int j,
                  List island)
  {
    visited[i,j] = true;
    island.Add(new Pair(i, j));
    for (int idx = 0; idx < 4; idx++) {
      int x = i + dirx[idx];
      int y = j + diry[idx];
      if (isValid(x, y)
          && grid[x,y] == 1
          && !visited[x,y]) {
        dfs(visited, grid, x, y, island);
      }
    }
  }
 
  // Function to check if
  // a point is inside grid
  static bool isValid(int x, int y)
  {
    if (x < 0 || x >= row
        || y < 0 || y >= col)
      return false;
    return true;
  }
 
  // Driver code
  public static void Main(String[] args)
  {
    int[,] grid = { { 1, 0, 0, 0, 1 },
                   { 1, 1, 0, 0, 0 },
                   { 0, 0, 0, 0, 0 },
                   { 0, 0, 1, 1, 1 } };
    closestDistance(grid);
  }
}
 
// This code is contributed by 29AjayKumar


Java
// Java code to implement the approach
 
import java.util.*;
 
class GFG {
    static int row;
    static int col;
 
    // A class to represent coordinates of
    // element in matrix
    static class Pair {
        int x;
        int y;
        int identity;
        Pair(int x, int y, int identity)
        {
            this.x = x;
            this.y = y;
            this.identity = identity;
        }
    }
 
    // Function to find closest distance
    static void closestDistance(int[][] grid)
    {
        row = grid.length;
        col = grid[0].length;
 
        int id = 1;
        Queue q = new ArrayDeque();
        int[][] visited = new int[row][col];
 
        // Distance array to store distance
        // From nearest island
        int[][] distance = new int[row][col];
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                if (grid[i][j] == 1
                    && visited[i][j] == 0) {
                    dfs(grid, visited, q, i, j, id);
                    id++;
                }
            }
        }
 
        // To store minimal distance
        // b/w closest islands
        int ans = bfs(grid, visited, distance, q);
        System.out.println(ans);
    }
 
    static int[] dirx = { 0, 1, 0, -1 };
    static int[] diry = { 1, 0, -1, 0 };
 
    // Dfs function to add all island elements
    // In queue and marking them visited with id
    static void dfs(int[][] grid, int[][] visited,
                    Queue q, int i,
                    int j, int id)
    {
        visited[i][j] = id;
        q.add(new Pair(i, j, id));
        for (int idx = 0; idx < 4; idx++) {
            int x = i + dirx[idx];
            int y = j + diry[idx];
            if (isValid(x, y) && grid[x][y] == 1
                && visited[x][y] == 0) {
                dfs(grid, visited, q, x, y, id);
            }
        }
    }
 
    // Bfs function to expand every island and
    // Maintaining distance array
    static int bfs(int[][] grid, int[][] visited,
                   int[][] distance, Queue q)
    {
        while (q.size() != 0) {
            Pair p = q.remove();
            for (int i = 0; i < 4; i++) {
                int x = p.x + dirx[i];
                int y = p.y + diry[i];
                if (isValid(x, y)
                    && visited[x][y] == 0) {
                    q.add(new Pair(x, y,
                                   p.identity));
                    distance[x][y]
                        = distance[p.x][p.y] + 1;
                    visited[x][y]
                        = p.identity;
                }
                else if (isValid(x, y)
                         && visited[x][y] != 0
                         && visited[x][y]
                                != visited[p.x][p.y]) {
                    return distance[x][y]
                        + distance[p.x][p.y];
                }
            }
        }
        return -1;
    }
 
    // Function to check if point
    // Is inside grid
    static boolean isValid(int x, int y)
    {
        if (x < 0 || x >= row
            || y < 0 || y >= col)
            return false;
        return true;
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        int[][] grid = { { 1, 0, 0, 0, 1 },
                         { 1, 1, 0, 0, 0 },
                         { 0, 0, 0, 0, 0 },
                         { 0, 0, 1, 1, 1 } };
        closestDistance(grid);
    }
}



输出
2

时间复杂度: O(N 4 )
辅助空间: O(N 2 )

有效的方法:

请按照以下步骤使用上述有效方法解决问题:

  • 创建两个二维数组“已访问”“距离”,初始化为 0。距离数组将存储到最近岛屿的距离。
  • 遍历网格,如果元素为“1”,则调用dfs以除 0 以外的任何数字标记访问数组中的相应元素。
    • 用不同的数字标记访问数组中的每个岛屿。
    • 在进行dfs遍历的同时,在队列中添加代表该元素的节点,该节点将在bfs中使用。
  • 使用前面步骤中创建的队列进行bfs遍历,并逐级扩展每个岛。
    • 如果网格中的相邻元素未标记为已访问,则将其标记为与已访问数组中当前节点相同的编号。
      • 将 {current node + 1} 的距离存储在相邻未访问元素的距离数组中。
    • 否则,如果网格中的相邻元素已经被标记为已访问数组中的当前节点以外的某个数字。
      • 返回当前元素的距离+相邻元素的距离。

下面是实现方法的代码:

Java

// Java code to implement the approach
 
import java.util.*;
 
class GFG {
    static int row;
    static int col;
 
    // A class to represent coordinates of
    // element in matrix
    static class Pair {
        int x;
        int y;
        int identity;
        Pair(int x, int y, int identity)
        {
            this.x = x;
            this.y = y;
            this.identity = identity;
        }
    }
 
    // Function to find closest distance
    static void closestDistance(int[][] grid)
    {
        row = grid.length;
        col = grid[0].length;
 
        int id = 1;
        Queue q = new ArrayDeque();
        int[][] visited = new int[row][col];
 
        // Distance array to store distance
        // From nearest island
        int[][] distance = new int[row][col];
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                if (grid[i][j] == 1
                    && visited[i][j] == 0) {
                    dfs(grid, visited, q, i, j, id);
                    id++;
                }
            }
        }
 
        // To store minimal distance
        // b/w closest islands
        int ans = bfs(grid, visited, distance, q);
        System.out.println(ans);
    }
 
    static int[] dirx = { 0, 1, 0, -1 };
    static int[] diry = { 1, 0, -1, 0 };
 
    // Dfs function to add all island elements
    // In queue and marking them visited with id
    static void dfs(int[][] grid, int[][] visited,
                    Queue q, int i,
                    int j, int id)
    {
        visited[i][j] = id;
        q.add(new Pair(i, j, id));
        for (int idx = 0; idx < 4; idx++) {
            int x = i + dirx[idx];
            int y = j + diry[idx];
            if (isValid(x, y) && grid[x][y] == 1
                && visited[x][y] == 0) {
                dfs(grid, visited, q, x, y, id);
            }
        }
    }
 
    // Bfs function to expand every island and
    // Maintaining distance array
    static int bfs(int[][] grid, int[][] visited,
                   int[][] distance, Queue q)
    {
        while (q.size() != 0) {
            Pair p = q.remove();
            for (int i = 0; i < 4; i++) {
                int x = p.x + dirx[i];
                int y = p.y + diry[i];
                if (isValid(x, y)
                    && visited[x][y] == 0) {
                    q.add(new Pair(x, y,
                                   p.identity));
                    distance[x][y]
                        = distance[p.x][p.y] + 1;
                    visited[x][y]
                        = p.identity;
                }
                else if (isValid(x, y)
                         && visited[x][y] != 0
                         && visited[x][y]
                                != visited[p.x][p.y]) {
                    return distance[x][y]
                        + distance[p.x][p.y];
                }
            }
        }
        return -1;
    }
 
    // Function to check if point
    // Is inside grid
    static boolean isValid(int x, int y)
    {
        if (x < 0 || x >= row
            || y < 0 || y >= col)
            return false;
        return true;
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        int[][] grid = { { 1, 0, 0, 0, 1 },
                         { 1, 1, 0, 0, 0 },
                         { 0, 0, 0, 0, 0 },
                         { 0, 0, 1, 1, 1 } };
        closestDistance(grid);
    }
}


输出
2

时间复杂度: O(N 2 )
辅助空间: O(N 2 )