给定一个布尔二维矩阵,找出岛屿的数量。一组相连的 1 形成一个岛。例如,下面的矩阵包含 5 个岛
例子:
Input : mat[][] = {{1, 1, 0, 0, 0},
{0, 1, 0, 0, 1},
{1, 0, 0, 1, 1},
{0, 0, 0, 0, 0},
{1, 0, 1, 0, 1}
Output : 5
什么是岛?
一组相连的 1 形成一个岛。例如,下面的矩阵包含 5 个岛
{1, 1, 0, 0, 0},
{0, 1, 0, 0, 1},
{1, 0, 0, 1, 1},
{0, 0, 0, 0, 0},
{1, 0, 1, 0, 1}
这是标准问题的变体:连通分量。无向图的连通分量是一个子图,其中每两个顶点通过一条路径相互连接,并且不与子图外的其他顶点相连。
例如,下图显示了三个相连的组件。
所有顶点都相互连接的图只有一个连通分量,由整个图组成。这种只有一个连通分量的图称为强连通图。
我们已经讨论了针对岛屿的 DFS 解决方案。这个问题也可以通过在每个组件上应用 BFS() 来解决。在每次 BFS() 调用中,都会访问一个组件或子图。我们将在下一个未访问的组件上调用 BFS。对 BFS() 的调用次数给出了连接组件的数量。也可以使用 BFS。
二维矩阵中的一个单元格可以连接到 8 个邻居。因此,与我们处理所有相邻顶点的标准 BFS() 不同,我们只处理 8 个相邻顶点。我们会跟踪访问过的 1,以免再次访问它们。
C++
// A BFS based solution to count number of
// islands in a graph.
#include
using namespace std;
// R x C matrix
#define R 5
#define C 5
// A function to check if a given cell
// (u, v) can be included in DFS
bool isSafe(int mat[R][C], int i, int j,
bool vis[R][C])
{
return (i >= 0) && (i < R) &&
(j >= 0) && (j < C) &&
(mat[i][j] && !vis[i][j]);
}
void BFS(int mat[R][C], bool vis[R][C],
int si, int sj)
{
// These arrays are used to get row and
// column numbers of 8 neighbours of
// a given cell
int row[] = { -1, -1, -1, 0, 0, 1, 1, 1 };
int col[] = { -1, 0, 1, -1, 1, -1, 0, 1 };
// Simple BFS first step, we enqueue
// source and mark it as visited
queue > q;
q.push(make_pair(si, sj));
vis[si][sj] = true;
// Next step of BFS. We take out
// items one by one from queue and
// enqueue their univisited adjacent
while (!q.empty()) {
int i = q.front().first;
int j = q.front().second;
q.pop();
// Go through all 8 adjacent
for (int k = 0; k < 8; k++) {
if (isSafe(mat, i + row[k],
j + col[k], vis)) {
vis[i + row[k]][j + col[k]] = true;
q.push(make_pair(i + row[k], j + col[k]));
}
}
}
}
// This function returns number islands (connected
// components) in a graph. It simply works as
// BFS for disconnected graph and returns count
// of BFS calls.
int countIslands(int mat[R][C])
{
// Mark all cells as not visited
bool vis[R][C];
memset(vis, 0, sizeof(vis));
// Call BFS for every unvisited vertex
// Whenever we see an univisted vertex,
// we increment res (number of islands)
// also.
int res = 0;
for (int i = 0; i < R; i++) {
for (int j = 0; j < C; j++) {
if (mat[i][j] && !vis[i][j]) {
BFS(mat, vis, i, j);
res++;
}
}
}
return res;
}
// main function
int main()
{
int mat[][C] = { { 1, 1, 0, 0, 0 },
{ 0, 1, 0, 0, 1 },
{ 1, 0, 0, 1, 1 },
{ 0, 0, 0, 0, 0 },
{ 1, 0, 1, 0, 1 } };
cout << countIslands(mat);
return 0;
}
Java
// A BFS based solution to count number of
// islands in a graph.
import java.util.*;
class GFG
{
// R x C matrix
static final int R = 5;
static final int C = 5 ;
static class pair
{
int first, second;
public pair(int first, int second)
{
this.first = first;
this.second = second;
}
}
// A function to check if a given cell
// (u, v) can be included in DFS
static boolean isSafe(int mat[][], int i, int j,
boolean vis[][])
{
return (i >= 0) && (i < R) &&
(j >= 0) && (j < C) &&
(mat[i][j]==1 && !vis[i][j]);
}
static void BFS(int mat[][], boolean vis[][],
int si, int sj)
{
// These arrays are used to get row and
// column numbers of 8 neighbours of
// a given cell
int row[] = { -1, -1, -1, 0, 0, 1, 1, 1 };
int col[] = { -1, 0, 1, -1, 1, -1, 0, 1 };
// Simple BFS first step, we enqueue
// source and mark it as visited
Queue q = new LinkedList();
q.add(new pair(si, sj));
vis[si][sj] = true;
// Next step of BFS. We take out
// items one by one from queue and
// enqueue their univisited adjacent
while (!q.isEmpty())
{
int i = q.peek().first;
int j = q.peek().second;
q.remove();
// Go through all 8 adjacent
for (int k = 0; k < 8; k++)
{
if (isSafe(mat, i + row[k],
j + col[k], vis))
{
vis[i + row[k]][j + col[k]] = true;
q.add(new pair(i + row[k], j + col[k]));
}
}
}
}
// This function returns number islands (connected
// components) in a graph. It simply works as
// BFS for disconnected graph and returns count
// of BFS calls.
static int countIslands(int mat[][])
{
// Mark all cells as not visited
boolean [][]vis = new boolean[R][C];
// Call BFS for every unvisited vertex
// Whenever we see an univisted vertex,
// we increment res (number of islands)
// also.
int res = 0;
for (int i = 0; i < R; i++)
{
for (int j = 0; j < C; j++)
{
if (mat[i][j]==1 && !vis[i][j])
{
BFS(mat, vis, i, j);
res++;
}
}
}
return res;
}
// Driver code
public static void main(String[] args)
{
int mat[][] = { { 1, 1, 0, 0, 0 },
{ 0, 1, 0, 0, 1 },
{ 1, 0, 0, 1, 1 },
{ 0, 0, 0, 0, 0 },
{ 1, 0, 1, 0, 1 } };
System.out.print(countIslands(mat));
}
}
// This code is contributed by PrinciRaj1992
Python3
# A BFS based solution to count number of
# islands in a graph.
from collections import deque
# A function to check if a given cell
# (u, v) can be included in DFS
def isSafe(mat, i, j, vis):
return ((i >= 0) and (i < 5) and
(j >= 0) and (j < 5) and
(mat[i][j] and (not vis[i][j])))
def BFS(mat, vis, si, sj):
# These arrays are used to get row and
# column numbers of 8 neighbours of
# a given cell
row = [-1, -1, -1, 0, 0, 1, 1, 1]
col = [-1, 0, 1, -1, 1, -1, 0, 1]
# Simple BFS first step, we enqueue
# source and mark it as visited
q = deque()
q.append([si, sj])
vis[si][sj] = True
# Next step of BFS. We take out
# items one by one from queue and
# enqueue their univisited adjacent
while (len(q) > 0):
temp = q.popleft()
i = temp[0]
j = temp[1]
# Go through all 8 adjacent
for k in range(8):
if (isSafe(mat, i + row[k], j + col[k], vis)):
vis[i + row[k]][j + col[k]] = True
q.append([i + row[k], j + col[k]])
# This function returns number islands (connected
# components) in a graph. It simply works as
# BFS for disconnected graph and returns count
# of BFS calls.
def countIslands(mat):
# Mark all cells as not visited
vis = [[False for i in range(5)]
for i in range(5)]
# memset(vis, 0, sizeof(vis));
# 5all BFS for every unvisited vertex
# Whenever we see an univisted vertex,
# we increment res (number of islands)
# also.
res = 0
for i in range(5):
for j in range(5):
if (mat[i][j] and not vis[i][j]):
BFS(mat, vis, i, j)
res += 1
return res
# Driver code
if __name__ == '__main__':
mat = [ [ 1, 1, 0, 0, 0 ],
[ 0, 1, 0, 0, 1 ],
[ 1, 0, 0, 1, 1 ],
[ 0, 0, 0, 0, 0 ],
[ 1, 0, 1, 0, 1 ]]
print (countIslands(mat))
# This code is contributed by mohit kumar 29
C#
// A BFS based solution to count number of
// islands in a graph.
using System;
using System.Collections.Generic;
class GFG
{
// R x C matrix
static readonly int R = 5;
static readonly int C = 5 ;
class pair
{
public int first, second;
public pair(int first, int second)
{
this.first = first;
this.second = second;
}
}
// A function to check if a given cell
// (u, v) can be included in DFS
static bool isSafe(int [,]mat, int i, int j,
bool [,]vis)
{
return (i >= 0) && (i < R) &&
(j >= 0) && (j < C) &&
(mat[i, j]==1 && !vis[i, j]);
}
static void BFS(int [,]mat, bool [,]vis,
int si, int sj)
{
// These arrays are used to get row and
// column numbers of 8 neighbours of
// a given cell
int []row = { -1, -1, -1, 0, 0, 1, 1, 1 };
int []col = { -1, 0, 1, -1, 1, -1, 0, 1 };
// Simple BFS first step, we enqueue
// source and mark it as visited
List q = new List();
q.Add(new pair(si, sj));
vis[si, sj] = true;
// Next step of BFS. We take out
// items one by one from queue and
// enqueue their univisited adjacent
while (q.Count != 0)
{
int i = q[0].first;
int j = q[0].second;
q.RemoveAt(0);
// Go through all 8 adjacent
for (int k = 0; k < 8; k++)
{
if (isSafe(mat, i + row[k],
j + col[k], vis))
{
vis[i + row[k], j + col[k]] = true;
q.Add(new pair(i + row[k], j + col[k]));
}
}
}
}
// This function returns number islands (connected
// components) in a graph. It simply works as
// BFS for disconnected graph and returns count
// of BFS calls.
static int countIslands(int [,]mat)
{
// Mark all cells as not visited
bool [,]vis = new bool[R, C];
// Call BFS for every unvisited vertex
// Whenever we see an univisted vertex,
// we increment res (number of islands)
// also.
int res = 0;
for (int i = 0; i < R; i++)
{
for (int j = 0; j < C; j++)
{
if (mat[i, j]==1 && !vis[i, j])
{
BFS(mat, vis, i, j);
res++;
}
}
}
return res;
}
// Driver code
public static void Main(String[] args)
{
int [,]mat = { { 1, 1, 0, 0, 0 },
{ 0, 1, 0, 0, 1 },
{ 1, 0, 0, 1, 1 },
{ 0, 0, 0, 0, 0 },
{ 1, 0, 1, 0, 1 } };
Console.Write(countIslands(mat));
}
}
// This code is contributed by 29AjayKumar
Javascript
输出:
5
时间复杂度:O(ROW * COL),其中 ROW 是行数,COL 是矩阵中的 COLUMNS 数。
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。