给定一个维度为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
方法一——使用DFS Traversal :想法是使用DFS Traversal来统计被水包围的岛屿的数量。但是我们必须在给定矩阵的角落保持岛屿的轨迹,因为它们不会被计算在合成岛屿中。以下是步骤:
- 初始化一个二维访问矩阵(比如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
Javascript
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, 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
Javascript
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++
// 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
蟒蛇3
# Python3 program for the above approach
# DFS Traversal to find the count of
# island surrounded by water
def dfs(matrix, visited, x, y, n, m, hasCornerCell):
# If the land is already visited
# or there is no land or the
# coordinates gone out of matrix
# break function as there
# will be no islands
if (x < 0 or y < 0 or
x >= n or y >= m or
visited[x][y] == True or
matrix[x][y] == 0):
return
if (x == 0 or y == 0 or
x == n - 1 or y == m - 1):
if (matrix[x][y] == 1):
hasCornerCell = True
# Mark land as visited
visited[x][y] = True
# Traverse to all adjacent elements
dfs(matrix, visited, x + 1, y, n, m, hasCornerCell)
dfs(matrix, visited, x, y + 1, n, m, hasCornerCell)
dfs(matrix, visited, x - 1, y, n, m, hasCornerCell)
dfs(matrix, visited, x, y - 1, n, m, hasCornerCell)
# Function that counts the closed island
def countClosedIsland(matrix, n, m):
# Create boolean 2D visited matrix
# to keep track of visited cell
# Initially all elements are
# unvisited.
visited = [[False for i in range(m)]
for j in range(n)]
result = 0
# Mark visited all lands
# that are reachable from edge
for i in range(n):
for j in range(m):
if ((i != 0 and j != 0 and
i != n - 1 and j != m - 1) and
matrix[i][j] == 1 and
visited[i][j] == False):
# Determine if the island is closed
hasCornerCell = False
# hasCornerCell will be updated to
# true while DFS traversal if there
# is a cell with value '1' on the corner
dfs(matrix, visited, i, j,
n, m, hasCornerCell)
# If the island is closed
if (not hasCornerCell):
result = result + 1
# Return the final count
return result
# Driver Code
# Given size of Matrix
N, M = 5, 8
# Given Matrix
matrix = [ [ 0, 0, 0, 0, 0, 0, 0, 1 ],
[ 0, 1, 1, 1, 1, 0, 0, 1 ],
[ 0, 1, 0, 1, 0, 0, 0, 1 ],
[ 0, 1, 1, 1, 1, 0, 1, 0 ],
[ 0, 0, 0, 0, 0, 0, 0, 1 ] ]
# Function Call
print(countClosedIsland(matrix, N, M))
# This code is contributed by divyeshrabadiya07
C#
// C# program for the above approach
using System;
class GFG
{
// DFS Traversal to find the count of
// island surrounded by water
static void dfs(int[,] matrix, bool[,] visited,
int x, int y, int n, int m,
bool hasCornerCell)
{
// If the land is already visited
// or there is no land or the
// coordinates gone out of matrix
// break function as there
// will be no islands
if (x < 0 || y < 0 || x >= n || y >= m ||
visited[x, y] == true || matrix[x, y] == 0)
return;
if (x == 0 || y == 0 ||
x == n - 1 || y == m - 1)
{
if (matrix[x, y] == 1)
hasCornerCell = true;
}
// Mark land as visited
visited[x, y] = true;
// Traverse to all adjacent elements
dfs(matrix, visited, x + 1, y, n, m,
hasCornerCell);
dfs(matrix, visited, x, y + 1, n, m,
hasCornerCell);
dfs(matrix, visited, x - 1, y, n, m,
hasCornerCell);
dfs(matrix, visited, x, y - 1, n, m,
hasCornerCell);
}
// Function that counts the closed island
static int countClosedIsland(int[,] matrix, int n,
int m)
{
// Create boolean 2D visited matrix
// to keep track of visited cell
// Initially all elements are
// unvisited.
bool[,] visited = new bool[n, m];
int result = 0;
// Mark visited all lands
// that are reachable from edge
for(int i = 0; i < n; ++i)
{
for(int j = 0; j < m; ++j)
{
if ((i != 0 && j != 0 &&
i != n - 1 && j != m - 1) &&
matrix[i, j] == 1 &&
visited[i, j] == false)
{
// Determine if the island is closed
bool hasCornerCell = false;
// hasCornerCell will be updated to
// true while DFS traversal if there
// is a cell with value '1' on the corner
dfs(matrix, visited, i, j, n, m,
hasCornerCell);
// If the island is closed
if (!hasCornerCell)
result = result + 1;
}
}
}
// Return the final count
return result;
}
// Driver code
static void Main()
{
// Given size of Matrix
int N = 5, M = 8;
// Given Matrix
int[,] matrix = { { 0, 0, 0, 0, 0, 0, 0, 1 },
{ 0, 1, 1, 1, 1, 0, 0, 1 },
{ 0, 1, 0, 1, 0, 0, 0, 1 },
{ 0, 1, 1, 1, 1, 0, 1, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 1 } };
// Function Call
Console.WriteLine(countClosedIsland(matrix, N, M));
}
}
// This code is contributed by divyesh072019
Javascript
2
方法 2 – 使用BFS 遍历:想法是使用BFS访问拐角处值为 1 的每个单元格,然后遍历给定的矩阵,如果遇到任何未访问的值为 1 的单元格,则增加岛的计数并使所有为 1连接到它作为访问。以下是步骤:
- 初始化一个二维访问矩阵(比如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;
}
蟒蛇3
# 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 。
- 现在再次遍历矩阵,并为所有连接的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;
}
蟒蛇3
# 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)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。