最近的一对岛屿之间的距离
给定一个包含0s 和 1s的grid[][] ,其中“0”代表水, “1”代表土地。假设一个岛屿是一组四面被水(0s)包围的土地(1s)。
任务是找到两个最近的岛屿之间的距离,使得:
- 两个岛之间的距离是两个岛之间的最小“0”数。
- 只允许 4 个方向移动。
- 网格中至少存在 2 个岛屿。
例子:
Input: grid = {{1, 1, 0, 1, 1},
{1, 1, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 1, 1, 1}}
Output: 1
Explanation: There are three islands present in the grid.
Nearest pair of islands have only 1 zero (bolded in input grid) in between them.
Input: grid = {{1, 0, 0, 0, 1},
{1, 1, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 1, 1, 1}}
Output: 2
Explanation: There are three islands present in the grid.
Nearest pair of islands have 2 zeroes in between them (depicted by bold 0 in input grid).
In this case there are multiple pair of islands having distance 2 between them.
天真的方法:
The intuition is to find minimum distance between every possible pair of islands and return the minimum of all the distances, using DFS.
要找到 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 )
有效的方法:
The idea is that instead of finding distance between each island pair from the naive approach, optimize the task using Depth-first-search and breadth-first-search traversal techniques for individual operations, as mentioned below:
- First find all islands in the Grid using DFS
- Then find the minimum distance island pair among these, using BFS.
请按照以下步骤使用上述有效方法解决问题:
- 创建两个二维数组“已访问”和“距离”,初始化为 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 )