Islands in a graph using BFS
Last Updated :
20 Mar, 2023
Given a boolean 2D matrix, find the number of islands. A group of connected 1s forms an island. For example, the below matrix contains 5 islands
Example:
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
What is an island?
A group of connected 1s forms an island. For example, the below matrix contains 5 islands
{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}
This is a variation of the standard problem: connected component. A connected component of an undirected graph is a subgraph in which every two vertices are connected to each other by a path(s), and which is connected to no other vertices outside the subgraph.
For example, the graph shown below has three connected components.
A graph where all vertices are connected with each other has exactly one connected component, consisting of the whole graph. Such graph with only one connected component is called as Strongly Connected Graph.
We have discussed a DFS solution for islands is already discussed. This problem can also solved by applying BFS() on each component. In each BFS() call, a component or a sub-graph is visited. We will call BFS on the next un-visited component. The number of calls to BFS() gives the number of connected components. BFS can also be used.
A cell in 2D matrix can be connected to 8 neighbours. So, unlike standard BFS(), where we process all adjacent vertices, we process 8 neighbours only. We keep track of the visited 1s so that they are not visited again.
Algorithm:
- Initialize a boolean matrix of the same size as the given matrix to keep track of visited cells.
- Traverse the given matrix, and for each unvisited cell that is part of an island, perform BFS starting from that cell.
- In the BFS algorithm, enqueue the current cell and mark it as visited. Then, while the queue is not empty, dequeue a cell and enqueue its unvisited neighbors that are part of the same island. Mark each of these neighbors as visited.
- After BFS is complete, increment the island count by 1.
- Repeat steps 2-4 until all unvisited cells have been processed.
- Return the total island count.
C++
#include <bits/stdc++.h>
using namespace std;
#define R 5
#define C 5
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)
{
int row[] = { -1, -1, -1, 0, 0, 1, 1, 1 };
int col[] = { -1, 0, 1, -1, 1, -1, 0, 1 };
queue<pair< int , int > > q;
q.push(make_pair(si, sj));
vis[si][sj] = true ;
while (!q.empty()) {
int i = q.front().first;
int j = q.front().second;
q.pop();
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]));
}
}
}
}
int countIslands( int mat[R][C])
{
bool vis[R][C];
memset (vis, 0, sizeof (vis));
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;
}
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
import java.util.*;
class GFG
{
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;
}
}
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)
{
int row[] = { - 1 , - 1 , - 1 , 0 , 0 , 1 , 1 , 1 };
int col[] = { - 1 , 0 , 1 , - 1 , 1 , - 1 , 0 , 1 };
Queue<pair> q = new LinkedList<pair>();
q.add( new pair(si, sj));
vis[si][sj] = true ;
while (!q.isEmpty())
{
int i = q.peek().first;
int j = q.peek().second;
q.remove();
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]));
}
}
}
}
static int countIslands( int mat[][])
{
boolean [][]vis = new boolean [R][C];
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;
}
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));
}
}
|
Python3
from collections import deque
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):
row = [ - 1 , - 1 , - 1 , 0 , 0 , 1 , 1 , 1 ]
col = [ - 1 , 0 , 1 , - 1 , 1 , - 1 , 0 , 1 ]
q = deque()
q.append([si, sj])
vis[si][sj] = True
while ( len (q) > 0 ):
temp = q.popleft()
i = temp[ 0 ]
j = temp[ 1 ]
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]])
def countIslands(mat):
vis = [[ False for i in range ( 5 )]
for i in range ( 5 )]
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
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))
|
C#
using System;
using System.Collections.Generic;
class GFG
{
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;
}
}
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)
{
int []row = { -1, -1, -1, 0, 0, 1, 1, 1 };
int []col = { -1, 0, 1, -1, 1, -1, 0, 1 };
List<pair> q = new List<pair>();
q.Add( new pair(si, sj));
vis[si, sj] = true ;
while (q.Count != 0)
{
int i = q[0].first;
int j = q[0].second;
q.RemoveAt(0);
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]));
}
}
}
}
static int countIslands( int [,]mat)
{
bool [,]vis = new bool [R, C];
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;
}
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));
}
}
|
Javascript
<script>
let R = 5;
let C = 5 ;
function isSafe(mat,i,j,vis)
{
return (i >= 0) && (i < R) &&
(j >= 0) && (j < C) &&
(mat[i][j] == 1 && !vis[i][j]);
}
function BFS(mat, vis, si, sj)
{
let row = [ -1, -1, -1, 0, 0, 1, 1, 1 ];
let col = [ -1, 0, 1, -1, 1, -1, 0, 1 ];
let q = [];
q.push([si, sj]);
vis[si][sj] = true ;
while (q.length != 0)
{
let i = q[0][0];
let j = q[0][1];
q.shift();
for (let 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([i + row[k], j + col[k]]);
}
}
}
}
function countIslands(mat)
{
let vis = new Array(R);
for (let i = 0; i < R; i++)
{
vis[i] = new Array(C);
for (let j = 0; j < C; j++)
{
vis[i][j] = false ;
}
}
let res = 0;
for (let i = 0; i < R; i++)
{
for (let j = 0; j < C; j++)
{
if (mat[i][j] == 1 && !vis[i][j])
{
BFS(mat, vis, i, j);
res++;
}
}
}
return res;
}
let 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 ] ];
document.write(countIslands(mat));
</script>
|
Time Complexity: O(ROW * COL) where ROW is the number of ROWS and COL is the number of COLUMNS in the matrix.
Auxiliary Space: O(ROW * COL ) because of the visited array.
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...