Open In App

Find number of closed islands in given Matrix

Improve
Improve
Like Article
Like
Save
Share
Report

Given a binary matrix mat[][] of dimensions NxM such that 1 denotes the island and 0 denotes the water. The task is to find the number of closed islands in the given matrix. 

A closed island is known as the group of 1s that is surrounded by only 0s on all the four sides (excluding diagonals). If any 1 is at the edges of the given matrix then it is not considered as the part of the connected island as it is not surrounded by all 0
 

Examples: 

Input: N = 5, M = 8, 
mat[][] = 
{{0, 0, 0, 0, 0, 0, 0, 1}, 
{0, 1, 1, 1, 1, 0, 0, 1}, 
{0, 1, 0, 1, 0, 0, 0, 1}, 
{0, 1, 1, 1, 1, 0, 1, 0}, 
{0, 0, 0, 0, 0, 0, 0, 1}} 
Output:
Explanation: 
mat[][] = 
{{0, 0, 0, 0, 0, 0, 0, 1}, 
{0, 1, 1, 1, 1, 0, 0, 1}, 
{0, 1, 0, 1, 0, 0, 0, 1}, 
{0, 1, 1, 1, 1, 0, 1, 0}, 
{0, 0, 0, 0, 0, 0, 0, 1}} 
There are 2 closed islands. 
The islands in dark are closed because they are completely surrounded by 
0s (water). 
There are two more islands in the last column of the matrix, but they are not completely surrounded by 0s. 
Hence they are not closed islands.

Input: N = 3, M = 3, matrix[][] = 
{{1, 0, 0}, 
{0, 1, 0}, 
{0, 0, 1}} 
Output: 1

Recommended Practice

Method 1 – using DFS Traversal: The idea is to use DFS Traversal to count the number of island surrounded by water. But we have to keep the track of the island at the corner of the given matrix as they will not be counted in the resultant island. Below are the steps: 

  1. Initialize a 2D visited matrix(say vis[][]) to keep the track of traversed cell in the given matrix.
  2. Perform DFS Traversal on all the corner of the given matrix and if any element has value 1 then marked all the cell with value 1 as visited because it cannot be counted in the resultant count.
  3. Perform DFS Traversal on all the remaining unvisited cell and if value encountered is 1 then marked this cell as visited, count this island in the resultant count and recursively call DFS for all the 4 directions i.e., left, right, top, and bottom to make all the 1s connected to the current cell as visited.
  4. Repeat the above step until all cell with value 1 are not visited.

Below is the implementation of the above approach:

C++




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// DFS Traversal to find the count of
// island surrounded by water
void dfs(vector<vector<int> >& matrix,
         vector<vector<bool> >& visited, int x, int y,
         int n, int m)
{
    // If the land is already visited
    // or there is no land or the
    // coordinates gone out of matrix
    // break function as there
    // will be no islands
    if (x < 0 || y < 0 || x >= n || y >= m
        || visited[x][y] == true || matrix[x][y] == 0)
        return;
 
    // Mark land as visited
    visited[x][y] = true;
 
    // Traverse to all adjacent elements
    dfs(matrix, visited, x + 1, y, n, m);
    dfs(matrix, visited, x, y + 1, n, m);
    dfs(matrix, visited, x - 1, y, n, m);
    dfs(matrix, visited, x, y - 1, n, m);
}
 
// Function that counts the closed island
int countClosedIsland(vector<vector<int> >& matrix, int n,
                      int m)
{
 
    // Create boolean 2D visited matrix
    // to keep track of visited cell
 
    // Initially all elements are
    // unvisited.
    vector<vector<bool> > visited(n,
                                  vector<bool>(m, false));
 
    // Mark visited all lands
    // that are reachable from edge
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
 
            // Traverse corners
            if ((i * j == 0 || i == n - 1 || j == m - 1)
                and matrix[i][j] == 1
                and visited[i][j] == false)
                dfs(matrix, visited, i, j, n, m);
        }
    }
 
    // To stores number of closed islands
    int result = 0;
 
    for (int i = 0; i < n; ++i) {
 
        for (int j = 0; j < m; ++j) {
 
            // If the land not visited
            // then there will be atleast
            // one closed island
            if (visited[i][j] == false
                and matrix[i][j] == 1) {
 
                result++;
 
                // Mark all lands associated
                // with island visited.
                dfs(matrix, visited, i, j, n, m);
            }
        }
    }
 
    // Return the final count
    return result;
}
 
// Driver Code
int main()
{
    // Given size of Matrix
    int N = 5, M = 8;
 
    // Given Matrix
    vector<vector<int> > matrix
        = { { 0, 0, 0, 0, 0, 0, 0, 1 },
            { 0, 1, 1, 1, 1, 0, 0, 1 },
            { 0, 1, 0, 1, 0, 0, 0, 1 },
            { 0, 1, 1, 1, 1, 0, 1, 0 },
            { 0, 0, 0, 0, 0, 0, 0, 1 } };
 
    // Function Call
    cout << countClosedIsland(matrix, N, M);
    return 0;
}


Java




// Java program for the above approach
import java.util.*;
class GFG {
 
    // DFS Traversal to find the count of
    // island surrounded by water
    static void dfs(int[][] matrix, boolean[][] visited,
                    int x, int y, int n, int m)
    {
        // If the land is already visited
        // or there is no land or the
        // coordinates gone out of matrix
        // break function as there
        // will be no islands
        if (x < 0 || y < 0 || x >= n || y >= m
            || visited[x][y] == true || matrix[x][y] == 0)
            return;
 
        // Mark land as visited
        visited[x][y] = true;
 
        // Traverse to all adjacent elements
        dfs(matrix, visited, x + 1, y, n, m);
        dfs(matrix, visited, x, y + 1, n, m);
        dfs(matrix, visited, x - 1, y, n, m);
        dfs(matrix, visited, x, y - 1, n, m);
    }
 
    // Function that counts the closed island
    static int countClosedIsland(int[][] matrix, int n,
                                 int m)
    {
 
        // Create boolean 2D visited matrix
        // to keep track of visited cell
 
        // Initially all elements are
        // unvisited.
        boolean[][] visited = new boolean[n][m];
 
        // Mark visited all lands
        // that are reachable from edge
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < m; ++j) {
 
                // Traverse corners
                if ((i * j == 0 || i == n - 1 || j == m - 1)
                    && matrix[i][j] == 1
                    && visited[i][j] == false)
                    dfs(matrix, visited, i, j, n, m);
            }
        }
 
        // To stores number of closed islands
        int result = 0;
 
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < m; ++j) {
 
                // If the land not visited
                // then there will be atleast
                // one closed island
                if (visited[i][j] == false
                    && matrix[i][j] == 1) {
                    result++;
 
                    // Mark all lands associated
                    // with island visited.
                    dfs(matrix, visited, i, j, n, m);
                }
            }
        }
 
        // Return the final count
        return result;
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        // Given size of Matrix
        int N = 5, M = 8;
 
        // Given Matrix
        int[][] matrix = { { 0, 0, 0, 0, 0, 0, 0, 1 },
                           { 0, 1, 1, 1, 1, 0, 0, 1 },
                           { 0, 1, 0, 1, 0, 0, 0, 1 },
                           { 0, 1, 1, 1, 1, 0, 1, 0 },
                           { 0, 0, 0, 0, 0, 0, 0, 1 } };
 
        // Function Call
        System.out.print(countClosedIsland(matrix, N, M));
    }
}
 
// This code is contributed by Rohit_ranjan


Python3




# Python3 program for the above approach
 
# DFS Traversal to find the count of
# island surrounded by water
def dfs(matrix, visited, x, y, n, m):
     
    # If the land is already visited
    # or there is no land or the
    # coordinates gone out of matrix
    # break function as there
    # will be no islands
    if (x < 0 or y < 0 or
        x >= n or y >= m or
        visited[x][y] == True or
        matrix[x][y] == 0):
        return
         
    # Mark land as visited
    visited[x][y] = True
 
    # Traverse to all adjacent elements
    dfs(matrix, visited, x + 1, y, n, m);
    dfs(matrix, visited, x, y + 1, n, m);
    dfs(matrix, visited, x - 1, y, n, m);
    dfs(matrix, visited, x, y - 1, n, m);
 
# Function that counts the closed island
def countClosedIsland(matrix, n, m):
     
    # Create boolean 2D visited matrix
    # to keep track of visited cell
  
    # Initially all elements are
    # unvisited.
    visited = [[False for i in range(m)]
                      for j in range(n)]
 
    # Mark visited all lands
    # that are reachable from edge
    for i in range(n):
        for j in range(m):
             
            # Traverse corners
            if ((i * j == 0 or i == n - 1 or
                 j == m - 1) and matrix[i][j] == 1 and
                 visited[i][j] == False):
                dfs(matrix, visited, i, j, n, m)
 
    # To stores number of closed islands
    result = 0
 
    for i in range(n):
        for j in range(m):
             
            # If the land not visited
            # then there will be atleast
            # one closed island
            if (visited[i][j] == False and
                 matrix[i][j] == 1):
                result += 1
                 
                # Mark all lands associated
                # with island visited.
                dfs(matrix, visited, i, j, n, m)
 
    # Return the final count
    return result
 
#  Driver Code
 
# Given size of Matrix
N = 5
M = 8
 
# Given Matrix
matrix = [ [ 0, 0, 0, 0, 0, 0, 0, 1 ],
           [ 0, 1, 1, 1, 1, 0, 0, 1 ],
           [ 0, 1, 0, 1, 0, 0, 0, 1 ],
           [ 0, 1, 1, 1, 1, 0, 1, 0 ],
           [ 0, 0, 0, 0, 0, 0, 0, 1 ] ]
            
# Function Call
print(countClosedIsland(matrix, N, M))
 
# This code is contributed by rag2127


C#




// C# program for the above approach
using System;
 
class GFG {
 
    // DFS Traversal to find the count of
    // island surrounded by water
    static void dfs(int[, ] matrix, bool[, ] visited, int x,
                    int y, int n, int m)
    {
 
        // If the land is already visited
        // or there is no land or the
        // coordinates gone out of matrix
        // break function as there
        // will be no islands
        if (x < 0 || y < 0 || x >= n || y >= m
            || visited[x, y] == true || matrix[x, y] == 0)
            return;
 
        // Mark land as visited
        visited[x, y] = true;
 
        // Traverse to all adjacent elements
        dfs(matrix, visited, x + 1, y, n, m);
        dfs(matrix, visited, x, y + 1, n, m);
        dfs(matrix, visited, x - 1, y, n, m);
        dfs(matrix, visited, x, y - 1, n, m);
    }
 
    // Function that counts the closed island
    static int countClosedIsland(int[, ] matrix, int n,
                                 int m)
    {
 
        // Create bool 2D visited matrix
        // to keep track of visited cell
 
        // Initially all elements are
        // unvisited.
        bool[, ] visited = new bool[n, m];
 
        // Mark visited all lands
        // that are reachable from edge
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < m; ++j) {
 
                // Traverse corners
                if ((i * j == 0 || i == n - 1 || j == m - 1)
                    && matrix[i, j] == 1
                    && visited[i, j] == false)
                    dfs(matrix, visited, i, j, n, m);
            }
        }
 
        // To stores number of closed islands
        int result = 0;
 
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < m; ++j) {
 
                // If the land not visited
                // then there will be atleast
                // one closed island
                if (visited[i, j] == false
                    && matrix[i, j] == 1) {
                    result++;
 
                    // Mark all lands associated
                    // with island visited.
                    dfs(matrix, visited, i, j, n, m);
                }
            }
        }
 
        // Return the readonly count
        return result;
    }
 
    // Driver Code
    public static void Main(String[] args)
    {
 
        // Given size of Matrix
        int N = 5, M = 8;
 
        // Given Matrix
        int[, ] matrix = { { 0, 0, 0, 0, 0, 0, 0, 1 },
                           { 0, 1, 1, 1, 1, 0, 0, 1 },
                           { 0, 1, 0, 1, 0, 0, 0, 1 },
                           { 0, 1, 1, 1, 1, 0, 1, 0 },
                           { 0, 0, 0, 0, 0, 0, 0, 1 } };
 
        // Function call
        Console.Write(countClosedIsland(matrix, N, M));
    }
}
 
// This code is contributed by amal kumar choubey


Javascript




<script>
 
    // JavaScript program for the above approach
     
    // DFS Traversal to find the count of
    // island surrounded by water
    function dfs(matrix, visited, x, y, n, m)
    {
        // If the land is already visited
        // or there is no land or the
        // coordinates gone out of matrix
        // break function as there
        // will be no islands
        if (x < 0 || y < 0 || x >= n || y >= m
            || visited[x][y] == true || matrix[x][y] == 0)
            return;
  
        // Mark land as visited
        visited[x][y] = true;
  
        // Traverse to all adjacent elements
        dfs(matrix, visited, x + 1, y, n, m);
        dfs(matrix, visited, x, y + 1, n, m);
        dfs(matrix, visited, x - 1, y, n, m);
        dfs(matrix, visited, x, y - 1, n, m);
    }
  
    // Function that counts the closed island
    function countClosedIsland(matrix, n, m)
    {
  
        // Create boolean 2D visited matrix
        // to keep track of visited cell
  
        // Initially all elements are
        // unvisited.
        let visited = new Array(n);
        for (let i = 0; i < n; ++i)
        {
            visited[i] = new Array(m);
            for (let j = 0; j < m; ++j)
            {
                visited[i][j] = false;
            }
        }
         
  
        // Mark visited all lands
        // that are reachable from edge
        for (let i = 0; i < n; ++i) {
            for (let j = 0; j < m; ++j) {
  
                // Traverse corners
                if ((i * j == 0 || i == n - 1 || j == m - 1)
                    && matrix[i][j] == 1
                    && visited[i][j] == false)
                    dfs(matrix, visited, i, j, n, m);
            }
        }
  
        // To stores number of closed islands
        let result = 0;
  
        for (let i = 0; i < n; ++i) {
            for (let j = 0; j < m; ++j) {
  
                // If the land not visited
                // then there will be atleast
                // one closed island
                if (visited[i][j] == false
                    && matrix[i][j] == 1) {
                    result++;
  
                    // Mark all lands associated
                    // with island visited.
                    dfs(matrix, visited, i, j, n, m);
                }
            }
        }
  
        // Return the final count
        return result;
    }
     
    // Given size of Matrix
    let N = 5, M = 8;
 
    // Given Matrix
    let matrix = [ [ 0, 0, 0, 0, 0, 0, 0, 1 ],
      [ 0, 1, 1, 1, 1, 0, 0, 1 ],
      [ 0, 1, 0, 1, 0, 0, 0, 1 ],
      [ 0, 1, 1, 1, 1, 0, 1, 0 ],
      [ 0, 0, 0, 0, 0, 0, 0, 1 ] ];
 
    // Function Call
    document.write(countClosedIsland(matrix, N, M));
 
</script>


Output

2

Time Complexity: O(N*M) 
Auxiliary Space: O(N*M) 

Method: Single DFS Traversal

Improvement over Method 1: In the above Method 1, we see that we are calling DFS traversal twice (Once over the corner cells with ‘1’ and afterward over the cells which are not on the corners with ‘1’ and are not visited). We can solve this using only 1 DFS traversal. the idea is to call DFS for the cells with value ‘1’  which are not on the corners and while doing so, if we find a cell with value ‘1’ on the corner, then that means it should not be counted as an island. The code is shown below:

C++




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// DFS Traversal to find the count of
// island surrounded by water
void dfs(vector<vector<int> >& matrix,
         vector<vector<bool> >& visited, int x, int y,
         int n, int m, bool &hasCornerCell)
{
    // If the land is already visited
    // or there is no land or the
    // coordinates gone out of matrix
    // break function as there
    // will be no islands
    if (x < 0 || y < 0 || x >= n || y >= m
        || visited[x][y] == true || matrix[x][y] == 0)
        return;
 
      // Check for the corner cell
    if(x == 0 || y == 0 || x == n-1 || y == m-1)
    {
      if(matrix[x][y] == 1)
        hasCornerCell = true;
    }
   
    // Mark land as visited
    visited[x][y] = true;
 
    // Traverse to all adjacent elements
    dfs(matrix, visited, x + 1, y, n, m, hasCornerCell);
    dfs(matrix, visited, x, y + 1, n, m, hasCornerCell);
    dfs(matrix, visited, x - 1, y, n, m, hasCornerCell);
    dfs(matrix, visited, x, y - 1, n, m, hasCornerCell);
}
 
// Function that counts the closed island
int countClosedIsland(vector<vector<int> >& matrix, int n,
                      int m)
{
 
    // Create boolean 2D visited matrix
    // to keep track of visited cell
 
    // Initially all elements are
    // unvisited.
    vector<vector<bool>> visited(n,vector<bool>(m, false));
 
    // Store the count of islands
    int result = 0; 
   
    // Call DFS on the cells which
    // are not on corners with value '1'
    for (int i = 0; i < n; ++i)
    {
        for (int j = 0; j < m; ++j)
        {
 
            if ((i != 0 && j != 0 && i != n - 1 && j != m - 1)
                and matrix[i][j] == 1
                and visited[i][j] == false)
            {
               
                // Determine if the island is closed
                  bool hasCornerCell = false;
                   
                /* hasCornerCell will be
                 updated to true while DFS traversal
                if there is a cell with value
                 '1' on the corner */
                dfs(matrix, visited, i, j, n,
                              m, hasCornerCell);
                 
                /* If the island is closed*/
                  if(!hasCornerCell)
                  result = result + 1;
            }
        }
    }
 
    // Return the final count
    return result;
}
 
// Driver Code
int main()
{
    // Given size of Matrix
    int N = 5, M = 8;
 
    // Given Matrix
    vector<vector<int> > matrix
        = { { 0, 0, 0, 0, 0, 0, 0, 1 },
            { 0, 1, 1, 1, 1, 0, 0, 1 },
            { 0, 1, 0, 1, 0, 0, 0, 1 },
            { 0, 1, 1, 1, 1, 0, 1, 0 },
            { 0, 0, 0, 0, 0, 0, 0, 1 } };
 
    // Function Call
    cout << countClosedIsland(matrix, N, M);
    return 0;
}


Java




// Java program for the above approach
import java.util.*;
 
class GFG{
 
// DFS Traversal to find the count of
// island surrounded by water
static void dfs(int[][] matrix, boolean[][] visited,
                int x, int y, int n, int m,
                boolean hasCornerCell)
{
     
    // If the land is already visited
    // or there is no land or the
    // coordinates gone out of matrix
    // break function as there
    // will be no islands
    if (x < 0 || y < 0 || x >= n || y >= m ||
        visited[x][y] == true || matrix[x][y] == 0)
        return;
 
    if (x == 0 || y == 0 ||
        x == n - 1 || y == m - 1)
    {
        if (matrix[x][y] == 1)
            hasCornerCell = true;
    }
 
    // Mark land as visited
    visited[x][y] = true;
 
    // Traverse to all adjacent elements
    dfs(matrix, visited, x + 1, y, n, m,
        hasCornerCell);
    dfs(matrix, visited, x, y + 1, n, m,
        hasCornerCell);
    dfs(matrix, visited, x - 1, y, n, m,
        hasCornerCell);
    dfs(matrix, visited, x, y - 1, n, m,
        hasCornerCell);
}
 
// Function that counts the closed island
static int countClosedIsland(int[][] matrix, int n,
                             int m)
{
     
    // Create boolean 2D visited matrix
    // to keep track of visited cell
 
    // Initially all elements are
    // unvisited.
    boolean[][] visited = new boolean[n][m];
    int result = 0;
     
    // Mark visited all lands
    // that are reachable from edge
    for(int i = 0; i < n; ++i)
    {
        for(int j = 0; j < m; ++j)
        {
            if ((i != 0 && j != 0 &&
                 i != n - 1 && j != m - 1) &&
                 matrix[i][j] == 1 &&
                 visited[i][j] == false)
            {
 
                // Determine if the island is closed
                boolean hasCornerCell = false;
 
                // hasCornerCell will be updated to
                // true while DFS traversal if there
                // is a cell with value '1' on the corner
                dfs(matrix, visited, i, j, n, m,
                    hasCornerCell);
 
                // If the island is closed
                if (!hasCornerCell)
                    result = result + 1;
            }
        }
    }
 
    // Return the final count
    return result;
}
 
// Driver Code
public static void main(String[] args)
{
     
    // Given size of Matrix
    int N = 5, M = 8;
 
    // Given Matrix
    int[][] matrix = { { 0, 0, 0, 0, 0, 0, 0, 1 },
                       { 0, 1, 1, 1, 1, 0, 0, 1 },
                       { 0, 1, 0, 1, 0, 0, 0, 1 },
                       { 0, 1, 1, 1, 1, 0, 1, 0 },
                       { 0, 0, 0, 0, 0, 0, 0, 1 } };
 
    // Function Call
    System.out.print(countClosedIsland(matrix, N, M));
}
}
 
// This code is contributed by grand_master


Python3




# Python3 program for the above approach
 
# DFS Traversal to find the count of
# island surrounded by water
def dfs(matrix, visited, x, y, n, m, hasCornerCell):
     
    # If the land is already visited
    # or there is no land or the
    # coordinates gone out of matrix
    # break function as there
    # will be no islands
    if (x < 0 or y < 0 or
        x >= n or y >= m or
        visited[x][y] == True or
         matrix[x][y] == 0):
        return
 
    if (x == 0 or y == 0 or
        x == n - 1 or y == m - 1):
        if (matrix[x][y] == 1):
            hasCornerCell = True
 
    # Mark land as visited
    visited[x][y] = True
 
    # Traverse to all adjacent elements
    dfs(matrix, visited, x + 1, y, n, m, hasCornerCell)
    dfs(matrix, visited, x, y + 1, n, m, hasCornerCell)
    dfs(matrix, visited, x - 1, y, n, m, hasCornerCell)
    dfs(matrix, visited, x, y - 1, n, m, hasCornerCell)
 
# Function that counts the closed island
def countClosedIsland(matrix, n, m):
     
    # Create boolean 2D visited matrix
    # to keep track of visited cell
 
    # Initially all elements are
    # unvisited.
    visited = [[False for i in range(m)]
                      for j in range(n)]
    result = 0
     
    # Mark visited all lands
    # that are reachable from edge
    for i in range(n):
        for j in range(m):
            if ((i != 0 and j != 0 and
                 i != n - 1 and j != m - 1) and
                 matrix[i][j] == 1 and
                visited[i][j] == False):
 
                # Determine if the island is closed
                hasCornerCell = False
 
                # hasCornerCell will be updated to
                # true while DFS traversal if there
                # is a cell with value '1' on the corner
                dfs(matrix, visited, i, j,
                    n, m, hasCornerCell)
 
                # If the island is closed
                if (not hasCornerCell):
                    result = result + 1
 
    # Return the final count
    return result
     
# Driver Code
 
# Given size of Matrix
N, M = 5, 8
 
# Given Matrix
matrix = [ [ 0, 0, 0, 0, 0, 0, 0, 1 ],
           [ 0, 1, 1, 1, 1, 0, 0, 1 ],
           [ 0, 1, 0, 1, 0, 0, 0, 1 ],
           [ 0, 1, 1, 1, 1, 0, 1, 0 ],
           [ 0, 0, 0, 0, 0, 0, 0, 1 ] ]
 
# Function Call
print(countClosedIsland(matrix, N, M))
 
# This code is contributed by divyeshrabadiya07


C#




// C# program for the above approach
using System;
class GFG
{
     
  // DFS Traversal to find the count of
  // island surrounded by water
  static void dfs(int[,] matrix, bool[,] visited,
                  int x, int y, int n, int m,
                  bool hasCornerCell)
  {
 
    // If the land is already visited
    // or there is no land or the
    // coordinates gone out of matrix
    // break function as there
    // will be no islands
    if (x < 0 || y < 0 || x >= n || y >= m ||
        visited[x, y] == true || matrix[x, y] == 0)
      return;
 
    if (x == 0 || y == 0 ||
        x == n - 1 || y == m - 1)
    {
      if (matrix[x, y] == 1)
        hasCornerCell = true;
    }
 
    // Mark land as visited
    visited[x, y] = true;
 
    // Traverse to all adjacent elements
    dfs(matrix, visited, x + 1, y, n, m,
        hasCornerCell);
    dfs(matrix, visited, x, y + 1, n, m,
        hasCornerCell);
    dfs(matrix, visited, x - 1, y, n, m,
        hasCornerCell);
    dfs(matrix, visited, x, y - 1, n, m,
        hasCornerCell);
  }
 
  // Function that counts the closed island
  static int countClosedIsland(int[,] matrix, int n,
                               int m)
  {
 
    // Create boolean 2D visited matrix
    // to keep track of visited cell
 
    // Initially all elements are
    // unvisited.
    bool[,] visited = new bool[n, m];
    int result = 0;
 
    // Mark visited all lands
    // that are reachable from edge
    for(int i = 0; i < n; ++i)
    {
      for(int j = 0; j < m; ++j)
      {
        if ((i != 0 && j != 0 &&
             i != n - 1 && j != m - 1) &&
            matrix[i, j] == 1 &&
            visited[i, j] == false)
        {
 
          // Determine if the island is closed
          bool hasCornerCell = false;
 
          // hasCornerCell will be updated to
          // true while DFS traversal if there
          // is a cell with value '1' on the corner
          dfs(matrix, visited, i, j, n, m,
              hasCornerCell);
 
          // If the island is closed
          if (!hasCornerCell)
            result = result + 1;
        }
      }
    }
 
    // Return the final count
    return result;
  }
 
  // Driver code
  static void Main()
  {
     
    // Given size of Matrix
    int N = 5, M = 8;
  
    // Given Matrix
    int[,] matrix = { { 0, 0, 0, 0, 0, 0, 0, 1 },
                       { 0, 1, 1, 1, 1, 0, 0, 1 },
                       { 0, 1, 0, 1, 0, 0, 0, 1 },
                       { 0, 1, 1, 1, 1, 0, 1, 0 },
                       { 0, 0, 0, 0, 0, 0, 0, 1 } };
  
    // Function Call
    Console.WriteLine(countClosedIsland(matrix, N, M));
  }
}
 
// This code is contributed by divyesh072019


Javascript




<script>
 
    // JavaScript program for the above approach
     
    // DFS Traversal to find the count of
    // island surrounded by water
    function dfs(matrix, visited, x, y, n, m, hasCornerCell)
    {
 
        // If the land is already visited
        // or there is no land or the
        // coordinates gone out of matrix
        // break function as there
        // will be no islands
        if (x < 0 || y < 0 || x >= n || y >= m ||
            visited[x][y] == true || matrix[x][y] == 0)
            return;
 
        if (x == 0 || y == 0 ||
            x == n - 1 || y == m - 1)
        {
            if (matrix[x][y] == 1)
                hasCornerCell = true;
        }
 
        // Mark land as visited
        visited[x][y] = true;
 
        // Traverse to all adjacent elements
        dfs(matrix, visited, x + 1, y, n, m,
            hasCornerCell);
        dfs(matrix, visited, x, y + 1, n, m,
            hasCornerCell);
        dfs(matrix, visited, x - 1, y, n, m,
            hasCornerCell);
        dfs(matrix, visited, x, y - 1, n, m,
            hasCornerCell);
    }
 
    // Function that counts the closed island
    function countClosedIsland(matrix, n, m)
    {
 
        // Create boolean 2D visited matrix
        // to keep track of visited cell
 
        // Initially all elements are
        // unvisited.
        let visited = new Array(n);
        for(let i = 0; i < n; ++i)
        {
            visited[i] = new Array(m);
            for(let j = 0; j < m; ++j)
            {
                visited[i][j] = false;
            }
        }
        let result = 0;
 
        // Mark visited all lands
        // that are reachable from edge
        for(let i = 0; i < n; ++i)
        {
            for(let j = 0; j < m; ++j)
            {
                if ((i != 0 && j != 0 &&
                     i != n - 1 && j != m - 1) &&
                     matrix[i][j] == 1 &&
                     visited[i][j] == false)
                {
 
                    // Determine if the island is closed
                    let hasCornerCell = false;
 
                    // hasCornerCell will be updated to
                    // true while DFS traversal if there
                    // is a cell with value '1' on the corner
                    dfs(matrix, visited, i, j, n, m, hasCornerCell);
 
                    // If the island is closed
                    if (!hasCornerCell)
                        result = result + 1;
                }
            }
        }
 
        // Return the final count
        return result;
    }
     
    // Given size of Matrix
    let N = 5, M = 8;
  
    // Given Matrix
    let matrix = [ [ 0, 0, 0, 0, 0, 0, 0, 1 ],
                       [ 0, 1, 1, 1, 1, 0, 0, 1 ],
                       [ 0, 1, 0, 1, 0, 0, 0, 1 ],
                       [ 0, 1, 1, 1, 1, 0, 1, 0 ],
                       [ 0, 0, 0, 0, 0, 0, 0, 1 ] ];
  
    // Function Call
    document.write(countClosedIsland(matrix, N, M));
     
</script>


Output

2

Time Complexity: O(N*M)
The time complexity of the above algorithm is O(N*M) where N and M are the number of rows and columns of the given matrix. We traverse the entire matrix once and then perform a DFS traversal over the islands.

Space Complexity: O(N*M)
The space complexity of the above algorithm is O(N*M) as we declare two boolean arrays of size N*M to keep track of visited cells.

Method 2 – using BFS Traversal: The idea is to visit every cell with value 1 at the corner using BFS and then traverse the given matrix and if any unvisited cell with value 1 is encountered then increment the count of the island and make all the 1s connected to it as visited. Below are the steps: 

  1. Initialize a 2D visited matrix(say vis[][]) to keep the track of traversed cell in the given matrix.
  2. Perform BFS Traversal on all the corner of the given matrix and if any element has value 1 then marked all the cell with value 1 as visited because it cannot be counted in the resultant count.
  3. Perform BFS Traversal on all the remaining unvisited cell and if value encountered is 1 then marked this cell as visited, count this island in the resultant count and marked every cell in all the 4 directions i.e., left, right, top, and bottom to make all the 1s connected to the current cell as visited.
  4. Repeat the above step until all cell with value 1 are not visited.
  5. Print the count of island after the above steps.

Below is the implementation of the above approach

C++




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
int dx[] = { -1, 0, 1, 0 };
int dy[] = { 0, 1, 0, -1 };
 
// DFS Traversal to find the count of
// island surrounded by water
void bfs(vector<vector<int> >& matrix,
         vector<vector<bool> >& visited,
         int x, int y, int n, int m)
{
    // To store the popped cell
    pair<int, int> temp;
 
    // To store the cell of BFS
    queue<pair<int, int> > Q;
 
    // Push the current cell
    Q.push({ x, y });
 
    // Until Q is not empty
    while (!Q.empty())
    {
 
        temp = Q.front();
        Q.pop();
 
        // Mark current cell
        // as visited
        visited[temp.first]
               [temp.second]
            = true;
 
        // Iterate in all four directions
        for (int i = 0; i < 4; i++)
        {
            int x = temp.first + dx[i];
            int y = temp.second + dy[i];
 
            // Cell out of the matrix
            if (x < 0 || y < 0
                || x >= n || y >= m
                || visited[x][y] == true
                || matrix[x][y] == 0)
            {
                continue;
            }
 
            // Check is adjacent cell is
            // 1 and not visited
            if (visited[x][y] == false
                && matrix[x][y] == 1)
            {
                Q.push({ x, y });
            }
        }
    }
}
 
// Function that counts the closed island
int countClosedIsland(vector<vector<int> >& matrix,
                      int n, int m)
{
 
    // Create boolean 2D visited matrix
    // to keep track of visited cell
 
    // Initially all elements are
    // unvisited.
    vector<vector<bool> > visited(
        n, vector<bool>(m, false));
 
    // Mark visited all lands
    // that are reachable from edge
    for (int i = 0; i < n; ++i)
    {
        for (int j = 0; j < m; ++j)
        {
 
            // Traverse corners
            if ((i * j == 0
                 || i == n - 1
                 || j == m - 1)
                and matrix[i][j] == 1
                and visited[i][j] == false)
            {
                bfs(matrix, visited,
                    i, j, n, m);
            }
        }
    }
 
    // To stores number of closed islands
    int result = 0;
 
    for (int i = 0; i < n; ++i)
    {
 
        for (int j = 0; j < m; ++j)
        {
 
            // If the land not visited
            // then there will be atleast
            // one closed island
            if (visited[i][j] == false
                and matrix[i][j] == 1)
            {
 
                result++;
 
                // Mark all lands associated
                // with island visited
                bfs(matrix, visited, i, j, n, m);
            }
        }
    }
 
    // Return the final count
    return result;
}
 
// Driver Code
int main()
{
    // Given size of Matrix
    int N = 5, M = 8;
 
    // Given Matrix
    vector<vector<int> > matrix
        = { { 0, 0, 0, 0, 0, 0, 0, 1 },
            { 0, 1, 1, 1, 1, 0, 0, 1 },
            { 0, 1, 0, 1, 0, 0, 0, 1 },
            { 0, 1, 1, 1, 1, 0, 1, 0 },
            { 0, 0, 0, 0, 0, 0, 0, 1 } };
 
    // Function Call
    cout << countClosedIsland(matrix, N, M);
    return 0;
}


Java




// Java program for the above approach
import java.util.LinkedList;
import java.util.Queue;
 
class GFG{
     
static int dx[] = { -1, 0, 1, 0 };
static int dy[] = { 0, 1, 0, -1 };
 
// To store the row and column index
// of the popped cell
static class Cell
{
    int first, second;
    Cell(int x, int y)
    {
        this.first = x;
        this.second = y;
    }
}
 
// BFS Traversal to find the count of
// island surrounded by water
static void bfs(int[][] matrix, boolean[][] visited,
                int x, int y, int n, int m)
{
     
    // To store the popped cell
    Cell temp;
 
    // To store the cell of BFS
    Queue<Cell> Q = new LinkedList<Cell>();
 
    // Push the current cell
    Q.add(new Cell(x, y));
 
    // Until Q is not empty
    while (!Q.isEmpty())
    {
        temp = Q.peek();
        Q.poll();
 
        // Mark current cell
        // as visited
        visited[temp.first][temp.second] = true;
 
        // Iterate in all four directions
        for(int i = 0; i < 4; i++)
        {
            int xIndex = temp.first + dx[i];
            int yIndex = temp.second + dy[i];
 
            // Cell out of the matrix
            if (xIndex < 0 || yIndex < 0 || xIndex >= n ||
                yIndex >= m || visited[xIndex][yIndex] == true ||
                matrix[xIndex][yIndex] == 0)
            {
                continue;
            }
 
            // Check is adjacent cell is
            // 1 and not visited
            if (visited[xIndex][yIndex] == false &&
                 matrix[xIndex][yIndex] == 1)
            {
                Q.add(new Cell(xIndex, yIndex));
            }
        }
    }
}
 
// Function that counts the closed island
static int countClosedIsland(int[][] matrix, int n,
                             int m)
{
     
    // Create boolean 2D visited matrix
    // to keep track of visited cell
 
    // Initially all elements are
    // unvisited.
    boolean[][] visited = new boolean[n][m];
 
    // Mark visited all lands
    // that are reachable from edge
    for(int i = 0; i < n; ++i)
    {
        for(int j = 0; j < m; ++j)
        {
             
            // Traverse corners
            if ((i * j == 0 || i == n - 1 || j == m - 1) &&
                matrix[i][j] == 1 && visited[i][j] == false)
            {
                bfs(matrix, visited, i, j, n, m);
            }
        }
    }
 
    // To stores number of closed islands
    int result = 0;
 
    for(int i = 0; i < n; ++i)
    {
        for(int j = 0; j < m; ++j)
        {
             
            // If the land not visited
            // then there will be atleast
            // one closed island
            if (visited[i][j] == false &&
                 matrix[i][j] == 1)
            {
                result++;
                 
                // Mark all lands associated
                // with island visited
                bfs(matrix, visited, i, j, n, m);
            }
        }
    }
 
    // Return the final count
    return result;
}
 
// Driver Code
public static void main(String[] args)
{
     
    // Given size of Matrix
    int N = 5, M = 8;
 
    // Given Matrix
    int[][] matrix = { { 0, 0, 0, 0, 0, 0, 0, 1 },
                       { 0, 1, 1, 1, 1, 0, 0, 1 },
                       { 0, 1, 0, 1, 0, 0, 0, 1 },
                       { 0, 1, 1, 1, 1, 0, 1, 0 },
                       { 0, 0, 0, 0, 0, 0, 0, 1 } };
 
    // Function Call
    System.out.println(countClosedIsland(matrix, N, M));
}
}
 
// This code is contributed by jainlovely450


Python3




# Python program for the above approach
dx = [-1, 0, 1, 0 ]
dy = [0, 1, 0, -1]
 
global matrix
 
# DFS Traversal to find the count of
# island surrounded by water
def bfs(x, y, n, m):
   
    # To store the popped cell
    temp = []
     
    # To store the cell of BFS
    Q = []
     
    # Push the current cell
    Q.append([x, y])
     
    # Until Q is not empty
    while(len(Q) > 0):
        temp = Q.pop()
         
        # Mark current cell
        # as visited
        visited[temp[0]][temp[1]] = True
         
        # Iterate in all four directions
        for i in range(4):
            x = temp[0] + dx[i]
            y = temp[1] + dy[i]
             
            # Cell out of the matrix
            if(x < 0 or y < 0 or x >= n or y >= n or visited[x][y] == True or matrix[x][y] == 0):
                continue
            # Check is adjacent cell is
            # 1 and not visited
            if(visited[x][y] == False and matrix[x][y] == 1):
                Q.append([x, y])
 
# Function that counts the closed island
def countClosedIsland(n, m):
     
    # Create boolean 2D visited matrix
    # to keep track of visited cell
  
    # Initially all elements are
    # unvisited.
    global visited
    visited = [[False for i in range(m)] for j in range(n)]
 
    # Mark visited all lands
    # that are reachable from edge
    for i in range(n):
        for j in range(m):
           
            # Traverse corners
            if((i * j == 0 or i == n - 1 or j == m - 1) and matrix[i][j] == 1 and visited[i][j] == False):
                bfs(i, j, n, m);
                 
    # To stores number of closed islands
    result = 0
    for i in range(n):
        for j in range(m):
           
            # If the land not visited
            # then there will be atleast
            # one closed island
            if(visited[i][j] == False and matrix[i][j] == 1):
                result += 1
                 
                # Mark all lands associated
                # with island visited
                bfs(i, j, n, m);
                 
    # Return the final count
    return result
   
# Driver Code
 
# Given size of Matrix
N = 5
M = 8
 
# Given Matrix
matrix = [[ 0, 0, 0, 0, 0, 0, 0, 1],
          [0, 1, 1, 1, 1, 0, 0, 1],
          [0, 1, 0, 1, 0, 0, 0, 1 ],
          [0, 1, 1, 1, 1, 0, 1, 0 ],
          [0, 0, 0, 0, 0, 0, 0, 1]]
 
# Function Call
print(countClosedIsland(N, M))
 
# This code is contributed by avanitrachhadiya2155


C#




// C# program for the above approach
using System;
using System.Collections.Generic;
class GFG {
     
    static int[,] matrix;
    static bool[,] visited;
    static int[] dx = {-1, 0, 1, 0 };
    static int[] dy = {0, 1, 0, -1};
      
    // DFS Traversal to find the count of
    // island surrounded by water
    static void bfs(int x, int y, int n, int m)
    {
        // To store the popped cell
        Tuple<int,int> temp;
  
        // To store the cell of BFS
        List<Tuple<int,int>> Q = new List<Tuple<int,int>>();
  
        // Push the current cell
        Q.Add(new Tuple<int, int>(x, y));
  
        // Until Q is not empty
        while(Q.Count <= 0)
        {
            temp = Q[0];
            Q.RemoveAt(0);
         
            // Mark current cell
            // as visited
            visited[temp.Item1,temp.Item2] = true;
  
            // Iterate in all four directions
            for(int i = 0; i < 4; i++)
            {
                int xIndex = temp.Item1 + dx[i];
                int yIndex = temp.Item2 + dy[i];
      
                // Cell out of the matrix
                if (xIndex < 0 || yIndex < 0 || xIndex >= n ||
                    yIndex >= m || visited[xIndex,yIndex] == true ||
                    matrix[xIndex,yIndex] == 0)
                {
                    continue;
                }
      
                // Check is adjacent cell is
                // 1 and not visited
                if (visited[xIndex,yIndex] == false &&
                     matrix[xIndex,yIndex] == 1)
                {
                    Q.Add(new Tuple<int, int>(x, y));
                }
            }
        }
    }
  
    // Function that counts the closed island
    static int countClosedIsland(int n, int m)
    {
        // Create boolean 2D visited matrix
        // to keep track of visited cell
  
        // Initially all elements are
        // unvisited.
        visited = new bool[n, m];
        for(int i = 0; i < n; i++)
        {
            for(int j = 0; j < m; j++)
            {
                visited[i,j] = false;
            }
        }
  
        // Mark visited all lands
        // that are reachable from edge
        for(int i = 0; i < n; i++)
        {
            for(int j = 0; j < m; j++)
            {
                // Traverse corners
                if((i * j == 0 || i == n - 1 || j == m - 1) && matrix[i,j] == 1 && visited[i,j] == false)
                {
                    bfs(i, j, n, m);
                }
            }
        }
  
        // To stores number of closed islands
        int result = 2;
        for(int i = 0; i < n; i++)
        {
            for(int j = 0; j < m; j++)
            {
                // If the land not visited
                // then there will be atleast
                // one closed island
                if(visited[i,j] == false && matrix[i,j] == 1)
                {
                    result = 2;
  
                    // Mark all lands associated
                    // with island visited
                    bfs(i, j, n, m);
                 }
             }
         }
  
        // Return the final count
        return result;
   }
    
  static void Main() {
    // Given size of Matrix
    int N = 5, M = 8;
  
    // Given Matrix
    matrix = new int[5,8]
    { { 0, 0, 0, 0, 0, 0, 0, 1 },
       { 0, 1, 1, 1, 1, 0, 0, 1 },
       { 0, 1, 0, 1, 0, 0, 0, 1 },
       { 0, 1, 1, 1, 1, 0, 1, 0 },
       { 0, 0, 0, 0, 0, 0, 0, 1 } };
  
    // Function Call
    Console.Write(countClosedIsland(N, M));
  }
}
 
// This code is contributed by rameshtravel07.


Javascript




<script>
    // Javascript program for the above approach
    let matrix;
    let visited;
    let dx = [-1, 0, 1, 0 ];
    let dy = [0, 1, 0, -1];
     
    // DFS Traversal to find the count of
    // island surrounded by water
    function bfs(x, y, n, m)
    {
        // To store the popped cell
        let temp;
 
        // To store the cell of BFS
        let Q = [];
 
        // Push the current cell
        Q.push([x, y]);
 
        // Until Q is not empty
        while(Q.length > 0)
        {
            temp = Q[0];
            Q.pop();
        
            // Mark current cell
            // as visited
            visited[temp[0]][temp[1]] = true;
 
            // Iterate in all four directions
            for(let i = 0; i < 4; i++)
            {
                let x = temp[0] + dx[i];
                let y = temp[1] + dy[i];
 
                // Cell out of the matrix
                if(x < 0 || y < 0 || x >= n || y >= n || visited[x][y] == true || matrix[x][y] == 0)
                {
                    continue;
                }
                // Check is adjacent cell is
                // 1 and not visited
                if(visited[x][y] == false && matrix[x][y] == 1)
                {
                    Q.push([x, y]);
                }
              }
        }
    }
 
    // Function that counts the closed island
    function countClosedIsland(n, m)
    {
        // Create boolean 2D visited matrix
        // to keep track of visited cell
 
        // Initially all elements are
        // unvisited.
        visited = new Array(n);
        for(let i = 0; i < n; i++)
        {
            visited[i] = new Array(m);
            for(let j = 0; j < m; j++)
            {
                visited[i][j] = false;
            }
        }
 
        // Mark visited all lands
        // that are reachable from edge
        for(let i = 0; i < n; i++)
        {
            for(let j = 0; j < m; j++)
            {
                // Traverse corners
                if((i * j == 0 || i == n - 1 || j == m - 1) && matrix[i][j] == 1 && visited[i][j] == false)
                {
                    bfs(i, j, n, m);
                }
            }
         }
 
        // To stores number of closed islands
        let result = 2;
        for(let i = 0; i < n; i++)
        {
            for(let j = 0; j < m; j++)
            {
                // If the land not visited
                // then there will be atleast
                // one closed island
                if(visited[i][j] == false && matrix[i][j] == 1)
                {
                    result += 1;
 
                    // Mark all lands associated
                    // with island visited
                    bfs(i, j, n, m);
                 }
             }
         }
 
        // Return the final count
        return result;
   }
    
  // Given size of Matrix
  let N = 5, M = 8;
 
  // Given Matrix
  matrix
    = [ [ 0, 0, 0, 0, 0, 0, 0, 1 ],
    [ 0, 1, 1, 1, 1, 0, 0, 1 ],
    [ 0, 1, 0, 1, 0, 0, 0, 1 ],
    [ 0, 1, 1, 1, 1, 0, 1, 0 ],
    [ 0, 0, 0, 0, 0, 0, 0, 1 ] ];
 
  // Function Call
  document.write(countClosedIsland(matrix, N, M));
 
// This code is contributed by decode2207.
</script>


Output

2

Time Complexity: O(N*M) 
Auxiliary Space: O(N*M) 

Method 3 – using Disjoint-Set(Union-Find):

  1. Traverse the given matrix and change all the 1s and connected at the corners of the matrix to 0s.
  2. Now traverse the matrix again, and for all set of connected 1s create an edges connecting to all the 1s.
  3. Find the connected components for all the edges stored using Disjoint-Set Approach.
  4. Print the count of components after the above steps.

Below is the implementation of the above approach: 

C++




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function that implements the Find
int Find(vector<int>& hashSet, int val)
{
 
    // Get the val
    int parent = val;
 
    // Until parent is not found
    while (parent != hashSet[parent]) {
        parent = hashSet[parent];
    }
 
    // Return the parent
    return parent;
}
 
// Function that implements the Union
void Union(vector<int>& hashSet,
           int first, int second)
{
 
    // Find the first father
    int first_father = Find(hashSet, first);
 
    // Find the second father
    int second_father = Find(hashSet, second);
 
    // If both are unequals then update
    // first father as ssecond_father
    if (first_father != second_father)
        hashSet[first_father] = second_father;
}
 
// Recursive Function that change all
// the corners connected 1s to 0s
void change(vector<vector<char> >& matrix,
            int x, int y, int n, int m)
{
 
    // If already zero then return
    if (x < 0 || y < 0 || x > m - 1
        || y > n - 1 || matrix[x][y] == '0')
        return;
 
    // Change the current cell to '0'
    matrix[x][y] = '0';
 
    // Recursive Call for all the
    // four corners
    change(matrix, x + 1, y, n, m);
    change(matrix, x, y + 1, n, m);
    change(matrix, x - 1, y, n, m);
    change(matrix, x, y - 1, n, m);
}
 
// Function that changes all the
// connected 1s to 0s at the corners
void changeCorner(vector<vector<char> >& matrix)
{
    // Dimensions of matrix
    int m = matrix.size();
    int n = matrix[0].size();
 
    // Traverse the matrix
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
 
            // If corner cell
            if (i * j == 0 || i == m - 1
                || j == n - 1) {
 
                // If value is 1s, then
                // recursively change to 0
                if (matrix[i][j] == '1') {
                    change(matrix, i, j, n, m);
                }
            }
        }
    }
}
 
// Function that counts the number
// of island in the given matrix
int numIslands(vector<vector<char> >& matrix)
{
 
    if (matrix.size() == 0)
        return 0;
 
    // Dimensions of the matrix
    int m = matrix.size();
    int n = matrix[0].size();
 
    // Make all the corners connecting
    // 1s to zero
    changeCorner(matrix);
 
    // First convert to 1 dimension
    // position and convert all the
    // connections to edges
    vector<pair<int, int> > edges;
 
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
 
            // If the cell value is 1
            if (matrix[i][j] == '1') {
                int id = i * n + j;
 
                // Move right
                if (j + 1 < n) {
 
                    // If right cell is
                    // 1 then make it as
                    // an edge
                    if (matrix[i][j + 1] == '1') {
 
                        int right = i * n + j + 1;
 
                        // Push in edge vector
                        edges.push_back(make_pair(id, right));
                    }
                }
                // Move down
                if (i + 1 < m) {
 
                    // If right cell is
                    // 1 then make it as
                    // an edge
                    if (matrix[i + 1][j] == '1') {
                        int down = (i + 1) * n + j;
 
                        // Push in edge vector
                        edges.push_back(make_pair(id, down));
                    }
                }
            }
        }
    }
 
    // Construct the Union Find structure
    vector<int> hashSet(m * n, 0);
    for (int i = 0; i < m * n; i++) {
        hashSet[i] = i;
    }
 
    // Next apply Union Find for all
    // the edges stored
    for (auto edge : edges) {
        Union(hashSet, edge.first, edge.second);
    }
 
    // To count the number of connected
    // islands
    int numComponents = 0;
 
    // Traverse to find the islands
    for (int i = 0; i < m * n; i++) {
        if (matrix[i / n][i % n] == '1'
            && hashSet[i] == i)
            numComponents++;
    }
 
    // Return the count of the island
    return numComponents;
}
 
// Driver Code
int main()
{
    // Given size of Matrix
    int N = 5, M = 8;
 
    // Given Matrix
    vector<vector<char> > matrix
        = { { '0', '0', '0', '0', '0', '0', '0', '1' },
            { '0', '1', '1', '1', '1', '0', '0', '1' },
            { '0', '1', '0', '1', '0', '0', '0', '1' },
            { '0', '1', '1', '1', '1', '0', '1', '0' },
            { '0', '0', '0', '0', '0', '0', '0', '1' } };
 
    // Function Call
    cout << numIslands(matrix);
    return 0;
}


Java




// Java program for the above approach
import java.util.ArrayList;
 
class GFG{
 
static class Edge
{
    int first, second;
     
    Edge(int x, int y)
    {
        this.first = x;
        this.second = y;
    }
}
 
// Function that implements the Find
static int Find(int[] hashSet, int val)
{
     
    // Get the val
    int parent = val;
 
    // Until parent is not found
    while (parent != hashSet[parent])
    {
        parent = hashSet[parent];
    }
     
    // Return the parent
    return parent;
}
 
// Function that implements the Union
static void Union(int[] hashSet, int first, int second)
{
     
    // Find the first father
    int first_father = Find(hashSet, first);
 
    // Find the second father
    int second_father = Find(hashSet, second);
 
    // If both are unequals then update
    // first father as ssecond_father
    if (first_father != second_father)
        hashSet[first_father] = second_father;
}
 
// Recursive Function that change all
// the corners connected 1s to 0s
static void change(char[][] matrix, int x, int y,
                                    int n, int m)
{
     
    // If already zero then return
    if (x < 0 || y < 0 || x > m - 1 ||
        y > n - 1 || matrix[x][y] == '0')
        return;
 
    // Change the current cell to '0'
    matrix[x][y] = '0';
 
    // Recursive Call for all the
    // four corners
    change(matrix, x + 1, y, n, m);
    change(matrix, x, y + 1, n, m);
    change(matrix, x - 1, y, n, m);
    change(matrix, x, y - 1, n, m);
}
 
// Function that changes all the
// connected 1s to 0s at the corners
static void changeCorner(char[][] matrix)
{
     
    // Dimensions of matrix
    int m = matrix.length;
    int n = matrix[0].length;
 
    // Traverse the matrix
    for(int i = 0; i < m; i++)
    {
        for(int j = 0; j < n; j++)
        {
             
            // If corner cell
            if (i * j == 0 || i == m - 1 || j == n - 1)
            {
                 
                // If value is 1s, then
                // recursively change to 0
                if (matrix[i][j] == '1')
                {
                    change(matrix, i, j, n, m);
                }
            }
        }
    }
}
 
// Function that counts the number
// of island in the given matrix
static int numIslands(char[][] matrix)
{
    if (matrix.length == 0)
        return 0;
 
    // Dimensions of the matrix
    int m = matrix.length;
    int n = matrix[0].length;
 
    // Make all the corners connecting
    // 1s to zero
    changeCorner(matrix);
 
    // First convert to 1 dimension
    // position and convert all the
    // connections to edges
    ArrayList<Edge> edges = new ArrayList<Edge>();
 
    for(int i = 0; i < m; i++)
    {
        for(int j = 0; j < n; j++)
        {
             
            // If the cell value is 1
            if (matrix[i][j] == '1')
            {
                int id = i * n + j;
 
                // Move right
                if (j + 1 < n)
                {
                     
                    // If right cell is
                    // 1 then make it as
                    // an edge
                    if (matrix[i][j + 1] == '1')
                    {
                        int right = i * n + j + 1;
 
                        // Push in edge vector
                        edges.add(new Edge(id, right));
                    }
                }
                 
                // Move down
                if (i + 1 < m)
                {
                     
                    // If right cell is
                    // 1 then make it as
                    // an edge
                    if (matrix[i + 1][j] == '1')
                    {
                        int down = (i + 1) * n + j;
 
                        // Push in edge vector
                        edges.add(new Edge(id, down));
                    }
                }
            }
        }
    }
 
    // Construct the Union Find structure
    int[] hashSet = new int[m * n];
    for(int i = 0; i < m * n; i++)
    {
        hashSet[i] = i;
    }
 
    // Next apply Union Find for all
    // the edges stored
    for(Edge edge : edges)
    {
        Union(hashSet, edge.first, edge.second);
    }
 
    // To count the number of connected
    // islands
    int numComponents = 0;
 
    // Traverse to find the islands
    for(int i = 0; i < m * n; i++)
    {
        if (matrix[i / n][i % n] == '1' &&
            hashSet[i] == i)
            numComponents++;
    }
 
    // Return the count of the island
    return numComponents;
}
 
// Driver Code
public static void main(String[] args)
{
     
    // Given size of Matrix
    int N = 5, M = 8;
 
    // Given Matrix
    char[][] matrix = { { '0', '0', '0', '0',
                          '0', '0', '0', '1' },
                        { '0', '1', '1', '1',
                          '1', '0', '0', '1' },
                        { '0', '1', '0', '1',
                          '0', '0', '0', '1' },
                        { '0', '1', '1', '1',
                          '1', '0', '1', '0' },
                        { '0', '0', '0', '0',
                          '0', '0', '0', '1' } };
 
    // Function Call
    System.out.println(numIslands(matrix));
}
}
 
// This code is contributed by jainlovely450


Python3




# python 3 program for the above approach
 
# Function that implements the Find
def Find(hashSet, val):
   
    # Get the val
    parent = val
     
    # Until parent is not found
    while (parent != hashSet[parent]):
        parent = hashSet[parent]
 
    # Return the parent
    return parent
 
# Function that implements the Union
def Union(hashSet, first, second):
   
    # Find the first father
    first_father = Find(hashSet, first)
 
    # Find the second father
    second_father = Find(hashSet, second)
 
    # If both are unequals then update
    # first father as ssecond_father
    if (first_father != second_father):
        hashSet[first_father] = second_father
 
# Recursive Function that change all
# the corners connected 1s to 0s
def change(matrix, x, y, n, m):
   
    # If already zero then return
    if (x < 0 or y < 0 or x > m - 1 or y > n - 1 or matrix[x][y] == '0'):
        return
 
    # Change the current cell to '0'
    matrix[x][y] = '0'
 
    # Recursive Call for all the
    # four corners
    change(matrix, x + 1, y, n, m)
    change(matrix, x, y + 1, n, m)
    change(matrix, x - 1, y, n, m)
    change(matrix, x, y - 1, n, m)
 
# Function that changes all the
# connected 1s to 0s at the corners
def changeCorner(matrix):
   
    # Dimensions of matrix
    m = len(matrix)
    n = len(matrix[0])
 
    # Traverse the matrix
    for i in range(m):
        for j in range(n):
           
            # If corner cell
            if (i * j == 0 or i == m - 1 or j == n - 1):
               
                # If value is 1s, then
                # recursively change to 0
                if (matrix[i][j] == '1'):
                    change(matrix, i, j, n, m)
 
# Function that counts the number
# of island in the given matrix
def numIslands(matrix):
    if (len(matrix) == 0):
        return 0
 
    # Dimensions of the matrix
    m = len(matrix)
    n = len(matrix[0])
 
    # Make all the corners connecting
    # 1s to zero
    changeCorner(matrix)
 
    # First convert to 1 dimension
    # position and convert all the
    # connections to edges
    edges = []
    for i in range(m):
        for j in range(n):
           
            # If the cell value is 1
            if (matrix[i][j] == '1'):
                id = i * n + j
 
                # Move right
                if (j + 1 < n):
                    # If right cell is
                    # 1 then make it as
                    # an edge
                    if (matrix[i][j + 1] == '1'):
                        right = i * n + j + 1
 
                        # Push in edge vector
                        edges.append([id, right])
                # Move down
                if (i + 1 < m):
                   
                    # If right cell is
                    # 1 then make it as
                    # an edge
                    if (matrix[i + 1][j] == '1'):
                        down = (i + 1) * n + j
 
                        # Push in edge vector
                        edges.append([id, down])
 
    # Construct the Union Find structure
    hashSet = [0 for i in range(m*n)]
    for i in range(m*n):
        hashSet[i] = i
 
    # Next apply Union Find for all
    # the edges stored
    for edge in edges:
        Union(hashSet, edge[0], edge[1])
 
    # To count the number of connected
    # islands
    numComponents = 0
 
    # Traverse to find the islands
    for i in range(m*n):
        if (matrix[i // n][i % n] == '1' and hashSet[i] == i):
            numComponents += 1
 
    # Return the count of the island
    return numComponents
 
# Driver Code
if __name__ == '__main__':
   
    # Given size of Matrix
    N = 5
    M = 8
 
    # Given Matrix
    matrix = [['0', '0', '0', '0', '0', '0', '0', '1'],
              ['0', '1', '1', '1', '1', '0', '0', '1'],
              ['0', '1', '0', '1', '0', '0', '0', '1'],
              ['0', '1', '1', '1', '1', '0', '1', '0'],
              ['0', '0', '0', '0', '0', '0', '0', '1']]
 
    # Function Call
    print(numIslands(matrix))
 
    # This code is contributed by bgangwar59.


Javascript




<script>
// JavaScript program for the above approach
 
// Function that implements the Find
function Find(hashSet, val)
{
 
    // Get the val
    var parent = val;
     
    // Until parent is not found
    while (parent != hashSet[parent]) {
      parent = hashSet[parent];
    }
   
    // Return the parent
    return parent;
  }
   
  // Function that implements the Union
  function Union(hashSet, first, second) {
    // Find the first father
    var first_father = Find(hashSet, first);
    // Find the second father
    var second_father = Find(hashSet, second);
   
    // If both are unequals then update
    // first father as ssecond_father
    if (first_father != second_father) {
      hashSet[first_father] = second_father;
    }
  }
   
  // Recursive Function that change all
  // the corners connected 1s to 0s
  function change(matrix, x, y, n, m) {
    // If already zero then return
    if (x < 0 || y < 0 || x > m - 1 || y > n - 1 || matrix[x][y] == "0") {
      return;
    }
     
    // Change the current cell to '0'
    matrix[x][y] = "0";
   
    // Recursive Call for all the
    // four corners
    change(matrix, x + 1, y, n, m);
    change(matrix, x, y + 1, n, m);
    change(matrix, x - 1, y, n, m);
    change(matrix, x, y - 1, n, m);
  }
   
  // Function that changes all the
  // connected 1s to 0s at the corners
  function changeCorner(matrix) {
    // Dimensions of matrix
    var m = matrix.length;
    var n = matrix[0].length;
   
    // Traverse the matrix
    for (let i = 0; i < m; i++) {
      for (let j = 0; j < n; j++) {
        // If corner cell
        if (i * j == 0 || i == m - 1 || j == n - 1) {
          // If value is 1s, then
          // recursively change to 0
          if (matrix[i][j] == "1") {
            change(matrix, i, j, n, m);
          }
        }
      }
    }
  }
   
  // Function that counts the number
  // of island in the given matrix
  function numIslands(matrix) {
    if (matrix.length == 0) {
      return 0;
    }
   
    // Dimensions of the matrix
    var m = matrix.length;
    var n = matrix[0].length;
   
    // Make all the corners connecting
    // 1s to zero
    changeCorner(matrix);
   
    // First convert to 1 dimension
    // position and convert all the
    // connections to edges
    var edges = [];
    for (let i = 0; i < m; i++) {
      for (let j = 0; j < n; j++) {
        // If the cell value is 1
        if (matrix[i][j] == "1") {
          id = i * n + j;
   
          // Move right
          if (j + 1 < n) {
            // If right cell is
            // 1 then make it as
            // an edge
            if (matrix[i][j + 1] == "1") {
              var right = i * n + j + 1;
   
              // Push in edge vector
              edges.push([id, right]);
            }
          }
          // Move down
          if (i + 1 < m) {
            // If right cell is
            // 1 then make it as
            // an edge
            if (matrix[i + 1][j] == "1") {
              var down = (i + 1) * n + j;
   
              // Push in edge vector
              edges.push([id, down]);
            }
          }
        }
      }
    }
    // Construct the Union Find structure
    var hashSet = Array(m * n).fill(0);
    for (let i = 0; i < m * n; i++) {
      hashSet[i] = i;
    }
    // Next apply Union Find for all
    // the edges stored
    for (let i =0; i<edges.length; i++ ) {
      Union(hashSet, edges[i][0], edges[i][1]);
    }
    // To count the number of connected
    // islands
    var numComponents = 0;
   
    // Traverse to find the islands
    for (let i = 0; i < m * n; i++) {
      if (matrix[parseInt(i / n)][i % n] == "1" && hashSet[i] == i) {
        numComponents += 1;
      }
    }
    // Return the count of the island
    return numComponents;
  }
   
  // Driver Code
  // Given size of Matrix
  var N = 5;
  var M = 8;
   
  // Given Matrix
  var matrix = [
    ["0", "0", "0", "0", "0", "0", "0", "1"],
    ["0", "1", "1", "1", "1", "0", "0", "1"],
    ["0", "1", "0", "1", "0", "0", "0", "1"],
    ["0", "1", "1", "1", "1", "0", "1", "0"],
    ["0", "0", "0", "0", "0", "0", "0", "1"],
  ];
   
  // Function Call
  document.write(numIslands(matrix));
   
  // This code is contributed by rdtank.
</script>


C#




using System;
using System.Collections.Generic;
 
class Program
{
    static int Find(List<int> hashSet, int val)
    {
        int parent = val;
 
        while (parent != hashSet[parent])
        {
            parent = hashSet[parent];
        }
 
        return parent;
    }
 
    static void Union(List<int> hashSet, int first, int second)
    {
        int first_father = Find(hashSet, first);
        int second_father = Find(hashSet, second);
 
        if (first_father != second_father)
            hashSet[first_father] = second_father;
    }
 
    static void Change(ref List<List<char>> matrix, int x, int y, int n, int m)
    {
        if (x < 0 || y < 0 || x > m - 1 || y > n - 1 || matrix[x][y] == '0')
            return;
 
        matrix[x][y] = '0';
 
        Change(ref matrix, x + 1, y, n, m);
        Change(ref matrix, x, y + 1, n, m);
        Change(ref matrix, x - 1, y, n, m);
        Change(ref matrix, x, y - 1, n, m);
    }
 
    static void ChangeCorner(ref List<List<char>> matrix)
    {
        int m = matrix.Count;
        int n = matrix[0].Count;
 
        for (int i = 0; i < m; i++)
        {
            for (int j = 0; j < n; j++)
            {
                if (i * j == 0 || i == m - 1 || j == n - 1)
                {
                    if (matrix[i][j] == '1')
                    {
                        Change(ref matrix, i, j, n, m);
                    }
                }
            }
        }
    }
 
    static int NumIslands(List<List<char>> matrix)
    {
        if (matrix.Count == 0)
            return 0;
 
        int m = matrix.Count;
        int n = matrix[0].Count;
 
        ChangeCorner(ref matrix);
 
        List<Tuple<int, int>> edges = new List<Tuple<int, int>>();
 
        for (int i = 0; i < m; i++)
        {
            for (int j = 0; j < n; j++)
            {
                if (matrix[i][j] == '1')
                {
                    int id = i * n + j;
 
                    if (j + 1 < n)
                    {
                        if (matrix[i][j + 1] == '1')
                        {
                            int right = i * n + j + 1;
                            edges.Add(new Tuple<int, int>(id, right));
                        }
                    }
 
                    if (i + 1 < m)
                    {
                        if (matrix[i + 1][j] == '1')
                        {
                            int down = (i + 1) * n + j;
                            edges.Add(new Tuple<int, int>(id, down));
                        }
                    }
                }
            }
        }
 
        List<int> hashSet = new List<int>(m * n);
        for (int i = 0; i < m * n; i++)
        {
            hashSet.Add(i);
        }
 
        foreach (Tuple<int, int> edge in edges)
        {
            Union(hashSet, edge.Item1, edge.Item2);
        }
 
        int numComponents = 0;
 
        for (int i = 0; i < m * n; i++)
            if (matrix[i / n][i %n] == '1' && hashSet[i]==i)
                numComponents++;
        return numComponents;
    }
    public static void Main()
    {
        // Given size of Matrix
        int N = 5, M = 8;
 
        // Given Matrix
         List<List<char>> matrix = new List<List<char>>() {
            new List<char> { '0', '0', '0', '0', '0', '0', '0', '1' },
            new List<char> { '0', '1', '1', '1', '1', '0', '0', '1' },
            new List<char> { '0', '1', '0', '1', '0', '0', '0', '1' },
            new List<char> { '0', '1', '1', '1', '1', '0', '1', '0' },
            new List<char> { '0', '0', '0', '0', '0', '0', '0', '1' }
        };
        // Function Call
        Console.WriteLine(NumIslands(matrix));
    }
}
 
     
        


Output

2

Time Complexity: O(N*M) 
Auxiliary Space: O(N*M) 



Last Updated : 11 Apr, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads