Open In App

Islands in a graph using BFS

Last Updated : 20 Mar, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

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:

  1. Initialize a boolean matrix of the same size as the given matrix to keep track of visited cells.
  2. Traverse the given matrix, and for each unvisited cell that is part of an island, perform BFS starting from that cell.
  3. 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.
  4. After BFS is complete, increment the island count by 1.
  5. Repeat steps 2-4 until all unvisited cells have been processed.
  6. Return the total island count.

C++




// A BFS based solution to count number of
// islands in a graph.
#include <bits/stdc++.h>
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<pair<int, int> > 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 unvisited 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<pair> q = new LinkedList<pair>();
    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 unvisited 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 unvisited 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<pair> q = new List<pair>();
    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 unvisited 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




<script>
// A BFS based solution to count number of
// islands in a graph.
 
// R x C matrix
let R = 5;
let C = 5 ;
 
// A function to check if a given cell
// (u, v) can be included in DFS
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)
{
 
    // These arrays are used to get row and
    // column numbers of 8 neighbours of
    // a given cell
       let row = [ -1, -1, -1, 0, 0, 1, 1, 1 ];
    let col = [ -1, 0, 1, -1, 1, -1, 0, 1 ];
  
    // Simple BFS first step, we enqueue
    // source and mark it as visited
    let q = [];
    q.push([si, sj]);
    vis[si][sj] = true;
  
    // Next step of BFS. We take out
    // items one by one from queue and
    // enqueue their unvisited adjacent
    while (q.length != 0)
    {
  
        let i = q[0][0];
        let j = q[0][1];
        q.shift();
  
        // Go through all 8 adjacent
        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]]);
            }
        }
    }
}
 
// This function returns number islands (connected
// components) in a graph. It simply works as
// BFS for disconnected graph and returns count
// of BFS calls.
function countIslands(mat)
{
 
    // Mark all cells as not visited
    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;
        }
    }
  
    // Call BFS for every unvisited vertex
    // Whenever we see an univisted vertex,
    // we increment res (number of islands)
    // also.
    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;
}
 
// Driver code
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));
 
// This code is contributed by patel2127.
</script>


Output: 

5

 

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. 



Previous Article
Next Article

Similar Reads

Traversal of a Graph in lexicographical order using BFS
C/C++ Code // C++ program to implement // the above approach #include &lt;bits/stdc++.h&gt; using namespace std; // Function to traverse the graph in // lexicographical order using BFS void LexiBFS(map&lt;char, set&lt;char&gt; &gt;&amp; G, char S, map&lt;char, bool&gt;&amp; vis) { // Stores nodes of the graph // at each level queue&lt;char&gt; q; /
9 min read
Detect Cycle in a Directed Graph using BFS
Given a directed graph, check whether the graph contains a cycle or not. Your function should return true if the given graph contains at least one cycle, else return false. For example, the following graph contains two cycles 0-&gt;1-&gt;2-&gt;3-&gt;0 and 2-&gt;4-&gt;2, so your function must return true. Recommended: Please solve it on "PRACTICE" f
11 min read
Check if a given directed graph is strongly connected | Set 2 (Kosaraju using BFS)
Given a directed graph, find out whether the graph is strongly connected or not. A directed graph is strongly connected if there is a path between any two pairs of vertices. There are different methods to check the connectivity of directed graph but one of the optimized method is Kosaraju’s DFS based simple algorithm. Kosaraju’s BFS based simple al
14 min read
Detect cycle in an undirected graph using BFS
Given an undirected graph, how to check if there is a cycle in the graph? For example, the following graph has a cycle of 1-0-2-1.  Recommended: Please solve it on "PRACTICE" first, before moving on to the solution.We have discussed cycle detection for the directed graph. We have also discussed a union-find algorithm for cycle detection in undirect
5 min read
Print the lexicographically smallest BFS of the graph starting from 1
Given a connected graph with N vertices and M edges. The task is to print the lexicographically smallest BFS traversal of the graph starting from 1. Note: The vertices are numbered from 1 to N.Examples: Input: N = 5, M = 5 Edges: 1 4 3 4 5 4 3 2 1 5 Output: 1 4 3 2 5 Start from 1, go to 4, then to 3 and then to 2 and to 5. Input: N = 3, M = 2 Edges
7 min read
When to use DFS or BFS to solve a Graph problem?
Generally, when we come across a graph problem, we might need to traverse the structure of the given graph or tree to find our solution to the problem. Our problem might be : To search for a particular node in the graph.To find the shortest distance from a node to any other node or to every other node.To count all the nodes.Or there can be more com
7 min read
BFS for Disconnected Graph
In the previous post, BFS only with a particular vertex is performed i.e. it is assumed that all vertices are reachable from the starting vertex. But in the case of a disconnected graph or any vertex that is unreachable from all vertex, the previous implementation will not give the desired output, so in this post, a modification is done in BFS. All
14 min read
0-1 BFS (Shortest Path in a Binary Weight Graph)
Given a graph where every edge has weight as either 0 or 1. A source vertex is also given in the graph. Find the shortest path from the source vertex to every other vertex.  For Example:  Input : Source Vertex = 0 and below graph Having vertices like(u,v,w): Edges: [[0,1,0], [0, 7, 1], [1,2,1], [1, 7, 1], [2, 3, 0], [2, 5, 0], [2, 8, 1], [3, 4, 1],
9 min read
Breadth First Search or BFS for a Graph
Breadth First Search (BFS) is a fundamental graph traversal algorithm. It involves visiting all the connected nodes of a graph in a level-by-level manner. In this article, we will look into the concept of BFS and how it can be applied to graphs effectively Table of Content Breadth First Search or BFS for a GraphRelation between BFS for Graph and BF
15 min read
Find the number of Islands using Disjoint Set
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 {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} A cell in the 2D matrix can be connected to 8 neighbours. This is a variation of the standard problem: “Counting the numbe
15+ min read
Article Tags :
Practice Tags :
three90RightbarBannerImg