给定尺寸为NxM的二进制矩阵mat [] [] ,使得1表示岛屿, 0表示水。任务是在给定的矩阵中找到闭合岛的数量。
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.
例子:
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: 2
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
方法1 –使用DFS穿越:想法是使用DFS穿越来计算被水包围的岛屿的数量。但是我们必须将岛的轨迹保持在给定矩阵的角上,因为它们不会在生成的岛中计算在内。步骤如下:
- 初始化2D访问的矩阵(例如vis [] [] ),以在给定的矩阵中保持对遍历单元格的跟踪。
- 在给定矩阵的所有角上执行DFS遍历,如果任何元素的值均为1,则将所有值为1的单元格标记为已访问,因为无法将其计入结果计数中。
- 在所有剩余的未访问单元上执行DFS遍历,如果遇到的值是1,则将该单元标记为已访问,在结果计数中计算该岛,然后针对所有4个方向(即左,右,上和下)递归调用DFS以进行访问时连接到当前单元的所有1 。
- 重复上述步骤,直到没有访问所有值为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连接到它访问。步骤如下:
- 初始化2D访问的矩阵(例如vis [] [] ),以在给定的矩阵中保持对遍历单元格的跟踪。
- 在给定矩阵的所有角上执行BFS遍历,如果任何元素的值为1,则将所有值为1的单元格标记为已访问,因为无法将其计入结果计数中。
- 在所有剩余的未访问单元上执行BFS遍历,如果遇到的值为1,则将该单元标记为已访问,将该岛计数为结果计数,并在所有4个方向(即左,右,上和下)上标记每个单元,以进行访问时连接到当前单元的所有1 。
- 重复上述步骤,直到没有访问所有值为1的单元格。
- 完成上述步骤后,打印岛数。
下面是上述方法的实现:
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更改为0 ,并将在矩阵角处连接的所有值都更改为0 。
- 现在再次遍历矩阵,并为所有连接的1创建一个连接到所有1的边。
- 查找使用“不相交集方法”存储的所有边的连接组件。
- 完成上述步骤后,打印组件数。
下面是上述方法的实现:
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)