Skip to content
Related Articles
Open in App
Not now

Related Articles

Distance between closest pair of islands

Improve Article
Save Article
  • Difficulty Level : Medium
  • Last Updated : 07 Feb, 2023
Improve Article
Save Article

Given a grid[][] containing 0s and 1s, where ‘0’ represents water and ‘1’ represents the land. Given that an island is a group of land (1s) surrounded by water (0s) on all sides.

The task is to find the distance between the two closest islands such that:

  • Distance between two islands is the minimum number of ‘0’ between two islands.
  • Only 4 – directional movement is allowed.
  • There are at least 2 islands present in the grid.

Examples:

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 a distance of 2 between them. 

 

Naive Approach: 

The intuition is to find minimum distance between every possible pair of islands and return the minimum of all the distances, using DFS.

To find minimum distance between 2 islands follow the below steps:

  • Store the coordinates of every islands separately in List / vector.
    • Create a boolean visited array to mark if an element has been visited.
    • Traverse the grid and if an element is ‘1’ and unvisited then call dfs to get all the elements corresponding island
    • Store coordinates of this island in list.
  • Find the minimum distance between every pair of islands in the list.
    • For every pair of island in list find the minimum distance between them.
      • distance between 2 islands will be the minimum distance between every pair of points in both islands.
  • Return the minimum of all the distances between islands.

Below is the code for the implementation of  approach:

C++




// CPP code to implement the approach
 
#include <bits/stdc++.h>
 
using namespace std;
 
int row;
int col;
 
// Function to check if
// a point is inside grid
bool isValid(int x, int y)
{
    if (x < 0 || x >= row
        || y < 0 || y >= col)
        return false;
    return true;
}
 
int dirx[] = { 0, 1, 0, -1 };
int diry[] = { 1, 0, -1, 0 };
 
void dfs(vector <vector<bool>> &visited,
                vector <vector<int>> &grid,
                int i, int j,
                vector <pair <int,int> > &island)
{
    visited[i][j] = true;
    island.push_back({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 find and
// store all islands in list
vector <vector <pair <int,int> > >
findIslands(vector <vector<int>> &grid)
{
 
    vector <vector <bool>> visited(row,vector <bool> (col,false));
    vector <vector <pair <int,int> > > list;
    for (int i = 0; i < row; i++) {
        for (int j = 0; j < col; j++) {
            if (grid[i][j] == 1
                && !visited[i][j]) {
                vector <pair <int,int> > island;
                dfs(visited, grid, i,
                    j, island);
                list.push_back(island);
            }
        }
    }
    return list;
}
 
// Function to find min distance
// between 2 islands
int findDistance(vector <pair <int,int> > &island1,
                        vector <pair <int,int> > &island2)
{
    int dist = INT_MAX;
    for (int i = 0; i < island1.size();
            i++) {
        pair <int,int> point1 = island1[i];
        for (int j = 0; j < island2.size();
                j++) {
            pair <int,int>  point2 = island2[j];
            int distp1p2
                = abs(point1.first - point2.first)
                    + abs(point1.second - point2.second)
                    - 1;
            dist = min(dist, distp1p2);
        }
    }
    return dist;
}
 
 
// Function to find closest distance
void closestDistance(vector <vector<int>> &grid)
{
    row = grid.size();
    col = grid[0].size();
 
    // List of coordinates
    // of all the islands
    vector <vector<pair <int,int>> > list
        = findIslands(grid);
 
    // Number of islands
    int n = list.size();
 
    // Variable to store
    // minimum of all distances
    int ans = INT_MAX;
    for (int i = 0; i < n - 1; i++) {
        for (int j = i + 1; j < n; j++) {
            vector <pair <int,int> > island1
                = list[i];
            vector <pair <int,int> > island2
                = list[j];
            int dist = findDistance(island1,
                                    island2);
            ans = min(dist, ans);
        }
    }
    cout<<ans<<endl;
}
 
 
 
int main(){
    vector <vector <int>> grid = { { 1, 0, 0, 0, 1 },
                        { 1, 1, 0, 0, 0 },
                        { 0, 0, 0, 0, 0 },
                        { 0, 0, 1, 1, 1 } };
    closestDistance(grid);
    return 0;
 
}
 
// This code is contributed by Sachin Sahara (sachin801)


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<ArrayList<Pair> > 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<Pair> island1
                    = list.get(i);
                ArrayList<Pair> 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<ArrayList<Pair> >
    findIslands(int[][] grid)
    {
 
        boolean[][] visited
            = new boolean[row][col];
        ArrayList<ArrayList<Pair> > 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<Pair> 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<Pair> island1,
                            ArrayList<Pair> 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<Pair> 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<Pair> > 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<Pair> island1
          = list[i];
        List<Pair> 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<List<Pair> >
    findIslands(int[,] grid)
  {
 
    bool[,] visited
      = new bool[row,col];
    List<List<Pair> > list
      = new List<List<Pair>>();
    for (int i = 0; i < row; i++) {
      for (int j = 0; j < col; j++) {
        if (grid[i,j] == 1
            && !visited[i,j]) {
          List<Pair> island
            = new List<Pair>();
          dfs(visited, grid, i,
              j, island);
          list.Add(island);
        }
      }
    }
    return list;
  }
 
  // Function to find min distance
  // between 2 islands
  static int findDistance(List<Pair> island1,
                          List<Pair> 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<Pair> 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


Javascript




// Javascript code to implement the approach
    var row, col;
 
    // A class to represent coordinates of
    // element in matrix
    class Pair{
        constructor(x, y)
        {
            this.x = x;
            this.y = y;
        }
    }
 
    // Function to find closest distance
    function closestDistance(grid)
    {
        row = grid.length;
        col = grid[0].length;
 
        // List of coordinates
        // of all the islands
        var list = findIslands(grid);
 
        // Number of islands
        n = list.length;
 
        // Variable to store
        // minimum of all distances
        ans = Number.MAX_SAFE_INTEGER;
        for (let i = 0 ; i < n - 1 ; i++) {
            for (let j = i + 1 ; j < n ; j++) {
                island1 = list[i];
                island2 = list[j];
                dist = findDistance(island1, island2);
                ans = Math.min(dist, ans);
            }
        }
        console.log(ans);
    }
 
    // Function to find and
    // store all islands in list
    function findIslands(grid)
    {
 
        var visited = new Array(row);
        for(let i = 0 ; i < row ; i++){
            visited[i] = new Array(col)
            for(let j = 0 ; j < col ; j++){
                visited[i][j] = false
            }
        }
 
        var list = new Array();
        for (let i = 0 ; i < row ; i++) {
            for (let j = 0 ; j < col ; j++) {
                if (grid[i][j] == 1 && !visited[i][j]) {
                    var island = new Array()
                    dfs(visited, grid, i,  j, island)
                    list.push(island)
                }
            }
        }
        return list
    }
 
    // Function to find min distance
    // between 2 islands
    function findDistance(island1, island2)
    {
        var dist = Number.MAX_SAFE_INTEGER;
        for (let i = 0 ; i < island1.length ; i++) {
            var point1 = island1[i];
            for (let j = 0 ; j < island2.length ; j++) {
                var point2 = island2[j];
                var distp1p2 = Math.abs(point1.x - point2.x) + Math.abs(point1.y - point2.y) - 1;
                dist = Math.min(dist, distp1p2);
            }
        }
        return dist;
    }
 
    var dirx = [ 0, 1, 0, -1 ];
    var diry = [ 1, 0, -1, 0 ];
 
    function dfs(visited, grid, i, j, island)
    {
        visited[i][j] = true;
        island.push(new Pair(i, j));
        for (let idx = 0; idx < 4; idx++) {
            var x = i + dirx[idx];
            var 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
    function isValid(x, y)
    {
        if (x < 0 || x >= row || y < 0 || y >= col){
            return false;
        }
        return true;
    }
 
    // Driver code
    var 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 subhamgoyal2014.


Python3




# A class to represent coordinates of
# element in matrix
 
 
class Pair:
    def __init__(self, x, y):
        self.x = x
        self.y = y
 
# Function to find closest distance
 
 
def closestDistance(grid, row, col):
 
  # List of coordinates of all the islands
    list = findIslands(grid, row, col)
    # Number of islands
    n = len(list)
    # Variable to store minimum of all distances
    ans = float('inf')
 
    for i in range(n - 1):
        for j in range(i + 1, n):
            island1 = list[i]
            island2 = list[j]
            dist = findDistance(island1, island2)
            ans = min(dist, ans)
 
    print(ans)
 
# Function to find and store all islands in list
 
 
def findIslands(grid, row, col):
 
    visited = [[False for j in range(col)] for i in range(row)]
 
    list = []
    for i in range(row):
        for j in range(col):
            if grid[i][j] == 1 and not visited[i][j]:
                island = []
                dfs(visited, grid, i, j, island, row, col)
                list.append(island)
 
    return list
 
# Function to find min distance between 2 islands
 
 
def findDistance(island1, island2):
    dist = float('inf')
 
    for i in range(len(island1)):
        point1 = island1[i]
        for j in range(len(island2)):
            point2 = island2[j]
            distp1p2 = abs(point1.x - point2.x) + abs(point1.y - point2.y) - 1
            dist = min(dist, distp1p2)
 
    return dist
 
 
dirx = [0, 1, 0, -1]
diry = [1, 0, -1, 0]
 
 
def dfs(visited, grid, i, j, island, row, col):
    visited[i][j] = True
    island.append(Pair(i, j))
 
    for idx in range(4):
        x = i + dirx[idx]
        y = j + diry[idx]
 
        if isValid(x, y, row, col) and grid[x][y] == 1 and not visited[x][y]:
            dfs(visited, grid, x, y, island, row, col)
 
# Function to check if a point is inside grid
 
 
def isValid(x, y, row, col):
    if x < 0 or x >= row or y < 0 or y >= col:
        return False
    return True
 
 
grid = [[1, 0, 0, 0, 1],
        [1, 1, 0, 0, 0],
        [0, 0, 0, 0, 0],
        [0, 0, 1, 1, 1]]
 
closestDistance(grid, len(grid), len(grid[0]))


 
 

Output

2

 

Time Complexity: O(N4)
Auxiliary Space: O(N2)

 

Efficient Approach: 

 

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.

 

Follow the steps to solve the problem using the above efficient approach:

 

  • Create two 2d arrays ‘visited’ and ‘distance’ initialized by 0. Distance array will be to store the distance to nearest island.
  • Traverse the grid and if an element is ‘1’ then call dfs to mark the corresponding element in visited array by any number other than 0.
    • Mark each island in the visited array by different numbers.
    • While doing dfs traversal simultaneously add node representing this element in queue which will be used in bfs.
  • Use the queue created in previous steps for bfs traversal and expand every island level by level.
    • if the neighboring element in grid is not marked visited then mark it visited with the same number as that of current node in visited array.
      • Store distance of {current node + 1} in the distance array for neighboring unvisited element.
    • else if neighboring element in grid is already marked visited with some number other than that of current node in visited array.
      • return distance of current element + distance of neighboring element.

 

Below is the code for the implementation of  approach:

 

C++




// CPP code to implement the approach
 
#include <bits/stdc++.h>
 
using namespace std;
 
int row;
int col;
 
struct 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 check if
// a point is inside grid
bool isValid(int x, int y)
{
    if (x < 0 || x >= row
        || y < 0 || y >= col)
        return false;
    return true;
}
 
int dirx[] = { 0, 1, 0, -1 };
int diry[] = { 1, 0, -1, 0 };
 
// Dfs function to add all island elements
// In queue and marking them visited with id
void dfs(vector <vector<int>> &grid, vector <vector<int>> &visited,
                queue <Pair> &q, int i,
                int j, int id)
{
    visited[i][j] = id;
    Pair p1(i, j, id);
    q.push(p1);
    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
int bfs(vector <vector<int>> &grid, vector <vector<int>> & visited,
                vector <vector<int>> & distance, queue<Pair> &q)
{
    while ( !q.empty() ) {
        Pair p = q.front();
        q.pop();
        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.push(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 find closest distance
void closestDistance(vector <vector <int>> &grid)
{
    row = grid.size();
    col = grid[0].size();
 
    int id = 1;
    queue <Pair> q;
    vector <vector <int>> visited(row,vector <int>(col,0));
 
    // Distance array to store distance
    // From nearest island
    vector <vector <int>> distance(row,vector <int>(col,0));
    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);
    cout << ans << endl;
}
 
 
int main(){
    vector <vector <int>> grid = { { 1, 0, 0, 0, 1 },
                        { 1, 1, 0, 0, 0 },
                        { 0, 0, 0, 0, 0 },
                        { 0, 0, 1, 1, 1 } };
    closestDistance(grid);
    return 0;
 
}
 
// This code is contributed by Sachin Sahara (sachin801)


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<Pair> q = new ArrayDeque<Pair>();
        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<Pair> 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<Pair> 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);
    }
}


 
 

Output

2

 

Time Complexity: O(N2)
Auxiliary Space: O(N2)

 


My Personal Notes arrow_drop_up
Related Articles

Start Your Coding Journey Now!