📜  在给定矩阵中找到封闭岛的数量

📅  最后修改于: 2021-04-29 13:48:51             🧑  作者: Mango

给定尺寸为NxM的二进制矩阵mat [] [] ,使得1表示岛屿, 0表示水。任务是在给定的矩阵中找到闭合岛的数量。

例子:

方法1 –使用DFS穿越想法是使用DFS穿越来计算被水包围的岛屿的数量。但是我们必须将岛的轨迹保持在给定矩阵的角上,因为它们不会在生成的岛中计算在内。步骤如下:

  1. 初始化2D访问的矩阵(例如vis [] [] ),以在给定的矩阵中保持对遍历单元格的跟踪。
  2. 在给定矩阵的所有角上执行DFS遍历,如果任何元素的值均为1,则将所有值为1的单元格标记为已访问,因为无法将其计入结果计数中。
  3. 在所有剩余的未访问单元上执行DFS遍历,如果遇到的值是1,则将该单元标记为已访问,在结果计数中计算该岛,然后针对所有4个方向(即左,右,上和下)递归调用DFS以进行访问时连接到当前单元的所有1
  4. 重复上述步骤,直到没有访问所有值为1的单元格。

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
 
// DFS Traversal to find the count of
// island surrounded by water
void dfs(vector >& matrix,
         vector >& 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 >& matrix, int n,
                      int m)
{
 
    // Create boolean 2D visited matrix
    // to keep track of visited cell
 
    // Initially all elements are
    // unvisited.
    vector > visited(n,
                                  vector(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 > 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


C++14
// C++ program for the above approach
#include 
using namespace std;
 
// DFS Traversal to find the count of
// island surrounded by water
void dfs(vector >& matrix,
         vector >& 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 >& matrix, int n,
                      int m)
{
 
    // Create boolean 2D visited matrix
    // to keep track of visited cell
 
    // Initially all elements are
    // unvisited.
    vector> visited(n,vector(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 > 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


C++
// C++ program for the above approach
#include 
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 >& matrix,
         vector >& visited,
         int x, int y, int n, int m)
{
    // To store the popped cell
    pair temp;
 
    // To store the cell of BFS
    queue > 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 >& matrix,
                      int n, int m)
{
 
    // Create boolean 2D visited matrix
    // to keep track of visited cell
 
    // Initially all elements are
    // unvisited.
    vector > visited(
        n, vector(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 > 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;
}


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
#include 
using namespace std;
 
// Function that implements the Find
int Find(vector& 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& 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 >& 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 >& 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 >& 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 > 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 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 > 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;
}


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.


输出
2

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

方法:单个DFS遍历

对方法1的改进:在上述方法1中,我们看到我们两次调用了DFS遍历(一次是在具有“ 1”的角单元上,然后是不在那些具有“ 1”的角上且未被访问的单元上) 。我们可以仅使用1次DFS遍历来解决此问题。这个想法是为不在拐角处的值为’1’的单元格调用DFS,这样做时,如果我们在拐角处找到了值为’1’的单元格,则意味着不应将其视为孤岛。代码如下所示:

C++ 14

// C++ program for the above approach
#include 
using namespace std;
 
// DFS Traversal to find the count of
// island surrounded by water
void dfs(vector >& matrix,
         vector >& 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 >& matrix, int n,
                      int m)
{
 
    // Create boolean 2D visited matrix
    // to keep track of visited cell
 
    // Initially all elements are
    // unvisited.
    vector> visited(n,vector(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 > 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

输出
2

方法2 –使用BFS遍历想法是使用BFS在拐角处访问每个值为1的像元,然后遍历给定的矩阵,如果遇到任何未访问的像元为1的像元,则增加孤岛的计数并使所有的1连接到它访问。步骤如下:

  1. 初始化2D访问的矩阵(例如vis [] [] ),以在给定的矩阵中保持对遍历单元格的跟踪。
  2. 在给定矩阵的所有角上执行BFS遍历,如果任何元素的值为1,则将所有值为1的单元格标记为已访问,因为无法将其计入结果计数中。
  3. 在所有剩余的未访问单元上执行BFS遍历,如果遇到的值为1,则将该单元标记为已访问,将该岛计数为结果计数,并在所有4个方向(即左,右,上和下)上标记每个单元,以进行访问时连接到当前单元的所有1
  4. 重复上述步骤,直到没有访问所有值为1的单元格。
  5. 完成上述步骤后,打印岛数。

下面是上述方法的实现:

C++

// C++ program for the above approach
#include 
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 >& matrix,
         vector >& visited,
         int x, int y, int n, int m)
{
    // To store the popped cell
    pair temp;
 
    // To store the cell of BFS
    queue > 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 >& matrix,
                      int n, int m)
{
 
    // Create boolean 2D visited matrix
    // to keep track of visited cell
 
    // Initially all elements are
    // unvisited.
    vector > visited(
        n, vector(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 > 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;
}

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
输出
2

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

方法3 –使用Disjoint-Set(Union-Find)

  1. 遍历给定的矩阵,并将所有1更改为0 ,并将在矩阵角处连接的所有值都更改为0
  2. 现在再次遍历矩阵,并为所有连接的1创建一个连接到所有1的边。
  3. 查找使用“不相交集方法”存储的所有边的连接组件。
  4. 完成上述步骤后,打印组件数。

下面是上述方法的实现:

C++

// C++ program for the above approach
#include 
using namespace std;
 
// Function that implements the Find
int Find(vector& 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& 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 >& 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 >& 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 >& 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 > 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 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 > 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;
}

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.
输出
2

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