Open In App

Number of Islands

Last Updated : 04 Apr, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

Given an n x m grid of 'W' (Water) and 'L' (Land), the task is to count the number of islands. An island is a group of adjacent 'L' cells connected horizontally, vertically, or diagonally, and it is surrounded by water or the grid boundary. The goal is to determine how many distinct islands exist in the grid.

Examples:

Input: grid[][] = [['L', 'L', 'W', 'W', 'W'],
                          ['W', 'L', 'W', 'W', 'L'],
                          ['L', 'W', 'W', 'L', 'L'],
                        ['W', 'W', 'W', 'W', 'W'],
                        ['L', 'W', 'L', 'L', 'W']]
Output: 4
Explanation: The image below shows all the 4 islands in the graph

2

Input: grid[][] = [['W', 'L', 'L', 'L', 'W', 'W', 'W'],
['W', 'W', 'L', 'L', 'W', 'L', 'W']]                         
Output: 2
Explanation: The image below shows all the 2 islands in the graph

1
Two islands in the matrix


Input: grid[][] = [['W,' 'W'],
                         ['W', 'W']]
Output: 0
All elements are 0, hence no islands.

Background

This is a variation of the standard problem: "Counting the number of connected components in an undirected graph".  Let us understand what is a 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. 

connected-components-in-an-undirected-graph
Connected components in an undirected graph

[Approach 1] Using DFS and Additional Matrix - O(n*m) Time and O(n*m) Space

The idea is to keep an additional matrix to keep track of the visited nodes in the given matrix, and perform dfs to find the total number of islands

Steps

  • Initialize count = 0 and boolean matrix, visited[][] to false.
  • For each cell of the input matrix check if the value of the current cell is L and is not visited , call for the dfs for all its 8 neighboring cells.
    • If the neighbor is safe to visit and is not visited already Call dfs recursively and Increment count by 1
  • Return count as the final answer.
C++
#include <bits/stdc++.h>
using namespace std;

// A function to check if a given
// cell (r, c) can be included in DFS
bool isSafe(vector<vector<char>>& grid, int r, int c, 
                vector<vector<bool>>& visited) {
    int row = grid.size();
    int col = grid[0].size();
  
    // r is in range, c is in range, value 
    // is 'L' (land) and not yet visited
    return (r >= 0) && (r < row) && (c >= 0) && 
           (c < col) && (grid[r][c] == 'L' && !visited[r][c]);
}

// A utility function to do DFS for a
// 2D boolean matrix. It only considers
// the 8 neighbours as adjacent vertices
void dfs(vector<vector<char>>& grid, int r, int c,
           vector<vector<bool>>& visited) {
  
    // These arrays are used to get
    // r and c numbers of 8
    // neighbours of a given cell
    vector<int> rNbr = { -1, -1, -1, 0, 0, 1, 1, 1 };
    vector<int> cNbr = { -1, 0, 1, -1, 1, -1, 0, 1 };

    // Mark this cell as visited
    visited[r][c] = true;

    // Recur for all connected neighbours
    for (int k = 0; k < 8; ++k) {
        int newR = r + rNbr[k];
        int newC = c + cNbr[k];
        if (isSafe(grid, newR, newC, visited)) {
            dfs(grid, newR, newC, visited);
        }
    }
}

// The main function that returns
// count of islands in a given boolean
// 2D matrix
int countIslands(vector<vector<char>>& grid) {
    int row = grid.size();
    int col = grid[0].size();
  
    // Make a bool array to mark visited cells.
    // Initially all cells are unvisited
    vector<vector<bool>> visited(row, vector<bool>(col, false));

    // Initialize count as 0 and traverse through
    // all cells of the given matrix
    int count = 0;
    for (int r = 0; r < row; ++r) {
        for (int c = 0; c < col; ++c) {
          
            // If a cell with value 'L' (land) is not visited yet,
            // then a new island is found
            if (grid[r][c] == 'L' && !visited[r][c]) {
               
                // Visit all cells in this island.
                dfs(grid, r, c, visited);
                
                // Increment the island count
                ++count;
            }
        }
    }
    return count;
}

int main() {
    // Updated grid with 'L' for land and 'W' for water
    vector<vector<char>> grid = { { 'L', 'W', 'W', 'W', 'W' },
                                  { 'W', 'L', 'W', 'W', 'L' },
                                  { 'L', 'W', 'W', 'L', 'L' },
                                  { 'W', 'W', 'W', 'W', 'W' },
                                  { 'L', 'W', 'L', 'L', 'W' } };

    cout << countIslands(grid) << endl;

    return 0;
}
Java
import java.util.*;

class GfG {

    // A function to check if a given
    // cell (r, c) can be included in DFS
    static boolean isSafe(char[][] grid, int r, int c, boolean[][] visited) {
        int row = grid.length;
        int col = grid[0].length;

        // r is in range, c is in range, value 
        // is 'L' (land) and not yet visited
        return (r >= 0) && (r < row) && (c >= 0) && 
               (c < col) && (grid[r][c] == 'L' && !visited[r][c]);
    }

    // A utility function to do DFS for a
    // 2D boolean matrix. It only considers
    // the 8 neighbours as adjacent vertices
    static void dfs(char[][] grid, int r, int c, boolean[][] visited) {
        // These arrays are used to get
        // r and c numbers of 8
        // neighbours of a given cell
        int[] rNbr = { -1, -1, -1, 0, 0, 1, 1, 1 };
        int[] cNbr = { -1, 0, 1, -1, 1, -1, 0, 1 };

        // Mark this cell as visited
        visited[r][c] = true;

        // Recur for all connected neighbours
        for (int k = 0; k < 8; ++k) {
            int newR = r + rNbr[k];
            int newC = c + cNbr[k];
            if (isSafe(grid, newR, newC, visited)) {
                dfs(grid, newR, newC, visited);
            }
        }
    }

    // The main function that returns
    // count of islands in a given boolean
    // 2D matrix
    static int countIslands(char[][] grid) {
        int row = grid.length;
        int col = grid[0].length;

        // Make a bool array to mark visited cells.
        // Initially all cells are unvisited
        boolean[][] visited = new boolean[row][col];

        // Initialize count as 0 and traverse through
        // all cells of the given matrix
        int count = 0;
        for (int r = 0; r < row; ++r) {
            for (int c = 0; c < col; ++c) {
                // If a cell with value 'L' (land) is not visited yet,
                // then a new island is found
                if (grid[r][c] == 'L' && !visited[r][c]) {
                    // Visit all cells in this island.
                    dfs(grid, r, c, visited);
                    
                    // Increment the island count
                    ++count;
                }
            }
        }
        return count;
    }

    public static void main(String[] args) {
        char[][] grid = {
            { 'L', 'L', 'W', 'W', 'W' },
            { 'W', 'L', 'W', 'W', 'L' },
            { 'L', 'W', 'W', 'L', 'L' },
            { 'W', 'W', 'W', 'W', 'W' },
            { 'L', 'W', 'L', 'L', 'W' }
        };

        System.out.println(countIslands(grid)); // Output the number of islands
    }
}
Python
def isSafe(grid, r, c, visited):
    row = len(grid)
    col = len(grid[0])
    
    return (0 <= r < row) and (0 <= c < col) and (grid[r][c] == 'L' and not visited[r][c])

def dfs(grid, r, c, visited):
    

    rNbr = [-1, -1, -1, 0, 0, 1, 1, 1]
    cNbr = [-1, 0, 1, -1, 1, -1, 0, 1]

    # Mark this cell as visited
    visited[r][c] = True

    # Recur for all connected neighbours
    for k in range(8):
        newR, newC = r + rNbr[k], c + cNbr[k]
        if isSafe(grid, newR, newC, visited):
            dfs(grid, newR, newC, visited)

def countIslands(grid):
    row = len(grid)
    col = len(grid[0])
    
    visited = [[False for _ in range(col)] for _ in range(row)]

    count = 0
    for r in range(row):
        for c in range(col):
            
            # If a cell with value 'L' (land) is not visited yet,
            # then a new island is found
            if grid[r][c] == 'L' and not visited[r][c]:
                
                # Visit all cells in this island.
                dfs(grid, r, c, visited)
                
                # increment the island count
                count += 1
    return count

if __name__ == "__main__":
    grid = [
        ['L', 'L', 'W', 'W', 'W'],
        ['W', 'L', 'W', 'W', 'L'],
        ['L', 'W', 'W', 'L', 'L'],
        ['W', 'W', 'W', 'W', 'W'],
        ['L', 'W', 'L', 'L', 'W']
    ]

    print(countIslands(grid)) 
C#
// C# Program to find the number of islands
// using DFS with additional matrix

using System;

class GfG {

    // A function to check if a given
    // cell (r, c) can be included in DFS
    static bool isSafe(char[,] grid, int r, int c, bool[,] visited) {
        int row = grid.GetLength(0);
        int col = grid.GetLength(1);

        // r is in range, c is in range, value 
        // is 'L' and not yet visited
        return (r >= 0 && r < row && c >= 0 && c < col && grid[r, c] == 'L' && !visited[r, c]);
    }

    // A utility function to do DFS for a
    // 2D boolean matrix. It only considers
    // the 8 neighbours as adjacent vertices
    static void dfs(char[,] grid, int r, int c, bool[,] visited) {
        int[] rNbr = { -1, -1, -1, 0, 0, 1, 1, 1 };
        int[] cNbr = { -1, 0, 1, -1, 1, -1, 0, 1 };

        visited[r, c] = true;

        for (int k = 0; k < 8; k++) {
            int newR = r + rNbr[k];
            int newC = c + cNbr[k];
            if (isSafe(grid, newR, newC, visited)) {
                dfs(grid, newR, newC, visited);
            }
        }
    }

    static int countIslands(char[,] grid) {
        int row = grid.GetLength(0);
        int col = grid.GetLength(1);
        bool[,] visited = new bool[row, col];

        int count = 0;
        for (int r = 0; r < row; r++) {
            for (int c = 0; c < col; c++) {
                if (grid[r, c] == 'L' && !visited[r, c]) {
                    dfs(grid, r, c, visited);
                    count++;
                }
            }
        }
        return count;
    }

    static void Main() {
        char[,] grid = {
            { 'L', 'L', 'W', 'W', 'W' },
            { 'W', 'L', 'W', 'W', 'L' },
            { 'L', 'W', 'W', 'L', 'L' },
            { 'W', 'W', 'W', 'W', 'W' },
            { 'L', 'W', 'L', 'L', 'W' }
        };

        Console.WriteLine(countIslands(grid)); 
    }
}
JavaScript
// JavaScript Program to find the number of islands
// using DFS with additional matrix

function isSafe(grid, r, c, visited) {
    const row = grid.length;
    const col = grid[0].length;
  
    // r is in range, c is in range, value 
    // is 'L' and not yet visited
    return (r >= 0 && r < row && c >= 0 && c < col && grid[r][c] === 'L' && !visited[r][c]);
}

// A utility function to do DFS for a 2D grid
// It only considers the 8 neighbours as adjacent vertices
function dfs(grid, r, c, visited) {
    const rNbr = [-1, -1, -1, 0, 0, 1, 1, 1];
    const cNbr = [-1, 0, 1, -1, 1, -1, 0, 1];
  
    visited[r][c] = true;
  
    // Recur for all connected neighbours
    for (let k = 0; k < 8; k++) {
        const newR = r + rNbr[k];
        const newC = c + cNbr[k];
        if (isSafe(grid, newR, newC, visited)) {
            dfs(grid, newR, newC, visited);
        }
    }
}

// Function to count the number of islands
function countIslands(grid) {
    const row = grid.length;
    const col = grid[0].length;
  
    // Create a visited matrix
    const visited = Array.from({ length: row }, () => Array(col).fill(false));

    let count = 0;
    // Traverse all cells in the grid
    for (let r = 0; r < row; r++) {
        for (let c = 0; c < col; c++) {
            if (grid[r][c] === 'L' && !visited[r][c]) {
                // If it's land and not visited, start DFS
                dfs(grid, r, c, visited);
                count++;  // Increment island count
            }
        }
    }
    return count;
}

// Example usage:
const grid = [
    ['L', 'L', 'W', 'W', 'W'],
    ['W', 'L', 'W', 'W', 'L'],
    ['L', 'W', 'W', 'L', 'L'],
    ['W', 'W', 'W', 'W', 'W'],
    ['L', 'W', 'L', 'L', 'W']
];

console.log(countIslands(grid));  

Output
4

[Approach 2] Using Space Optimized DFS - O(n*m) Time and O(1) Space

If we are allowed to modify the original matrix, we can avoid an additional visited matrix. Whenever we visit a cell in matrix, we change its value to W so that it is not visited again

C++
#include <bits/stdc++.h>
using namespace std;

void dfs(vector<vector<char>> &grid, int r, int c)
{
    int row = grid.size();
    int col = grid[0].size();

    // Base condition
    // if r or c is out of bounds or grid[r][c] is not 'L' (land)
    if (r < 0 || c < 0 || r >= row || c >= col || grid[r][c] != 'L')
    {
        return;
    }

    // Mark the cell as visited by setting it to 'W' (water)
    grid[r][c] = 'W';

    // Traverse all 8 possible directions
    vector<int> rNbr = {1, -1, 0, 0, 1, -1, 1, -1};
    vector<int> cNbr = {0, 0, 1, -1, 1, -1, -1, 1};

    for (int i = 0; i < 8; ++i)
    {
        int newR = r + rNbr[i];
        int newC = c + cNbr[i];
        dfs(grid, newR, newC);
    }
}

// Function to count the number of islands
int countIslands(vector<vector<char>> &grid)
{
    int row = grid.size();
    int col = grid[0].size();
    int count = 0;

    // Traverse the entire matrix
    for (int r = 0; r < row; r++)
    {
        for (int c = 0; c < col; c++)
        {

            // If a cell with value 'L' (land) is found
            if (grid[r][c] == 'L')
            {
                // Increment the island count
                count++;

                // Start DFS from the current cell
                dfs(grid, r, c);
            }
        }
    }
    return count;
}

int main()
{
    vector<vector<char>> grid =
    {
        {'L', 'L', 'W', 'W', 'W'},
        {'W', 'L', 'W', 'W', 'L'},
        {'L', 'W', 'W', 'L', 'L'},
        {'W', 'W', 'W', 'W', 'W'},
        {'L', 'W', 'L', 'L', 'W'}
    };

    cout << countIslands(grid) << endl; 
    return 0;
}
Java
class GfG {

    // A utility function to do DFS for a
    // 2D matrix. It only considers
    // the 8 neighbors as adjacent vertices
    static void dfs(char[][] grid, int r, int c)
    {

        // These arrays are used to get
        // r and c numbers of 8
        // neighbours of a given cell
        int row = grid.length;
        int col = grid[0].length;

        if (r < 0 || c < 0 || r >= row || c >= col
            || grid[r][c] != 'L') {
            return;
        }
        int[] rNbr = { -1, -1, -1, 0, 0, 1, 1, 1 };
        int[] cNbr = { -1, 0, 1, -1, 1, -1, 0, 1 };

        // Mark this cell as visited by setting it to 'W'
        grid[r][c] = 'W';

        // Recur for all connected neighbours
        for (int k = 0; k < 8; ++k) {
            int newR = r + rNbr[k];
            int newC = c + cNbr[k];

            dfs(grid, newR, newC);
        }
    }

    // The main function that returns
    // count of islands in a given matrix
    static int countIslands(char[][] grid)
    {
        int row = grid.length;
        int col = grid[0].length;

        // Initialize count as 0 and traverse through
        // all cells of the given matrix
        int count = 0;
        for (int r = 0; r < row; ++r) {
            for (int c = 0; c < col; ++c) {

                // If a cell with value 'L' (land) is found,
                // then a new island is found
                if (grid[r][c] == 'L') {

                    // Visit all cells in this island.
                    dfs(grid, r, c);

                    // Increment the island count
                    ++count;
                }
            }
        }
        return count;
    }

    public static void main(String[] args)
    {
        char[][] grid = { { 'L', 'L', 'W', 'W', 'W' },
                          { 'W', 'L', 'W', 'W', 'L' },
                          { 'L', 'W', 'W', 'L', 'L' },
                          { 'W', 'W', 'W', 'W', 'W' },
                          { 'L', 'W', 'L', 'L', 'W' } };

        System.out.println(countIslands(grid));
    }
}
Python
# A function to check if a given
# cell (r, c) can be included in DFS
def isSafe(grid, r, c):
    row = len(grid)
    col = len(grid[0])

    # r is in range, c is in range, value
    # is 'L' (land)
    return (0 <= r < row) and (0 <= c < col) and grid[r][c] == 'L'

# A utility function to do DFS for a
# 2D matrix. It only considers
# the 8 neighbors as adjacent vertices
def dfs(grid, r, c):
    # These arrays are used to get
    # r and c numbers of 8
    # neighbours of a given cell
    rNbr = [-1, -1, -1, 0, 0, 1, 1, 1]
    cNbr = [-1, 0, 1, -1, 1, -1, 0, 1]

    # Mark this cell as visited
    grid[r][c] = 'W'

    # Recur for all connected neighbours
    for k in range(8):
        newR = r + rNbr[k]
        newC = c + cNbr[k]
        if isSafe(grid, newR, newC):
            dfs(grid, newR, newC)

# The main function that returns
# count of islands in a given matrix
def countIslands(grid):
    row = len(grid)
    col = len(grid[0])

    count = 0
    for r in range(row):
        for c in range(col):
            if grid[r][c] == 'L':
                dfs(grid, r, c)
                count += 1
    return count

# Main execution
if __name__ == "__main__":
    grid = [
        ['L', 'L', 'W', 'W', 'W'],
        ['W', 'L', 'W', 'W', 'L'],
        ['L', 'W', 'W', 'L', 'L'],
        ['W', 'W', 'W', 'W', 'W'],
        ['L', 'W', 'L', 'L', 'W']
    ]
    print(countIslands(grid))  # Expected output: 4
C#
using System;

class GfG {

    // A utility function to check boundaries and if the cell is land
    static bool isSafe(char[,] grid, int r, int c, int row, int col) {
        return (r >= 0 && r < row && c >= 0 && c < col && grid[r, c] == 'L');
    }

    // A utility function to do DFS for a
    // 2D matrix. It only considers
    // the 8 neighbors as adjacent vertices
    static void dfs(char[,] grid, int r, int c, int row, int col) {
        // Check base condition
        if (r < 0 || c < 0 || r >= row || c >= col || grid[r, c] != 'L')
            return;

        // These arrays are used to get
        // r and c numbers of 8
        // neighbors of a given cell
        int[] rNbr = { -1, -1, -1, 0, 0, 1, 1, 1 };
        int[] cNbr = { -1, 0, 1, -1, 1, -1, 0, 1 };

        // Mark this cell as visited
        grid[r, c] = 'W';

        // Recur for all connected neighbors
        for (int k = 0; k < 8; ++k) {
            int newR = r + rNbr[k];
            int newC = c + cNbr[k];
            if (isSafe(grid, newR, newC, row, col)) {
                dfs(grid, newR, newC, row, col);
            }
        }
    }

    // The main function that returns
    // count of islands in a given matrix
    static int countIslands(char[,] grid) {
        int row = grid.GetLength(0);
        int col = grid.GetLength(1);

        // Initialize count as 0 and traverse through
        // all cells of the given matrix
        int count = 0;
        for (int r = 0; r < row; ++r) {
            for (int c = 0; c < col; ++c) {

                // If a cell with value 'L' (land) is found,
                // then a new island is found
                if (grid[r, c] == 'L') {

                    // Visit all cells in this island.
                    dfs(grid, r, c, row, col);

                    // Increment the island count
                    ++count;
                }
            }
        }
        return count;
    }

    static void Main(string[] args) {
        char[,] grid = {
            { 'L', 'L', 'W', 'W', 'W' },
            { 'W', 'L', 'W', 'W', 'L' },
            { 'L', 'W', 'W', 'L', 'L' },
            { 'W', 'W', 'W', 'W', 'W' },
            { 'L', 'W', 'L', 'L', 'W' }
        };

        Console.WriteLine(countIslands(grid)); 
    }
}
JavaScript
function isSafe(grid, r, c) {
    let row = grid.length;
    let col = grid[0].length;

    // r is in range, c is in range, value 
    // is 'L' (land) and not yet visited
    return r >= 0 && r < row && c >= 0 && c < col && grid[r][c] === 'L';
}


function dfs(grid, r, c) {
 
    let rNbr = [-1, -1, -1, 0, 0, 1, 1, 1];
    let cNbr = [-1, 0, 1, -1, 1, -1, 0, 1];

    // Mark this cell as visited
    grid[r][c] = 'W';

    // Recur for all connected neighbors
    for (let k = 0; k < 8; ++k) {
        let newR = r + rNbr[k];
        let newC = c + cNbr[k];
        if (isSafe(grid, newR, newC)) {
            dfs(grid, newR, newC);
        }
    }
}

// The main function that returns
// count of islands in a given matrix
function countIslands(grid) {
    let row = grid.length;
    let col = grid[0].length;

    let count = 0;
    for (let r = 0; r < row; ++r) {
        for (let c = 0; c < col; ++c) {

            // If a cell with value 'L' (land) is found,
            // then a new island is found
            if (grid[r][c] === 'L') {

                // Visit all cells in this island.
                dfs(grid, r, c);

                // increment the island count
                ++count;
            }
        }
    }
    return count;
}

// Test case with grid containing 'L' for land and 'W' for water
let grid = [
    ['L', 'L', 'W', 'W', 'W'],
    ['W', 'L', 'W', 'W', 'L'],
    ['L', 'W', 'W', 'L', 'L'],
    ['W', 'W', 'W', 'W', 'W'],
    ['L', 'W', 'L', 'L', 'W']
];

console.log(countIslands(grid));  // Expected output: 4

Output
4

[Approach 3] Using Breadth First Search - O(n*m) time and O(n*m) space

We can solve this problem using BFS as well. The idea is going to be same. We use a visited matrix to keep track if the visited cells and apply the standard queue based BFS algorithm to count islands. We increment the count whenever we see an unvisited vertex after the previous call. The time complexity and auxiliary space are going to be same as DFS. However this implementation would be faster as we do not have recursion overhead.

Please refer Islands in a graph using BFS for details.

[Approach 4] Using Disjoint Set - O(n*m) time and O(n*m) space

This solution is very intuitive if you have studied disjoint set data structures. We mainly create disjoint sets of all islands and the number of disjoint sets at the end is our answer.

Please refer Find the number of Islands Using Disjoint Set for details.



Next Article

Similar Reads