Number of Islands

Last Updated : 15 Aug, 2026

Given an n × m grid[][] consisting of 'L' (land) and 'W' (water), we need to count the total number of islands present in the grid without modifying the original grid.
An island is defined as a group of connected 'L' cells that are adjacent horizontally, vertically, or diagonally, and surrounded by water or the boundary of 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.

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
Try It Yourself
redirect icon

Using DFS with a Visited Matrix - O(n x m) Time and O(n x m) Space

Traverse the grid and whenever an unvisited 'L' is found, treat it as a new island and use DFS to visit all land cells connected to it in 8 directions. A separate visited matrix is used so that the original grid is not modified.

  • Create a visited matrix.
  • Traverse every cell of the grid.
  • For each unvisited 'L', increment the island count.
  • Run DFS and mark all connected land cells as visited.
  • Check all 8 directions during DFS.
  • Return the total island count.

Consider the grid:

file
  • Start from (0,0). It is an unvisited 'L', so islands = 1.
  • DFS visits (0,1) and (1,1). These cells belong to the same island.
  • Continue scanning. At (1,4), we find another unvisited 'L', so islands = 2.
  • DFS visits (2,3) and (2,4).
  • At (2,0), we find an unvisited 'L', so islands = 3.
  • At (4,0), we find another unvisited 'L', so islands = 4.
  • DFS visits (4,2) and (4,3) as part of the same island.
  • No unvisited land cells remain.

Therefore: Number of islands = 4

C++
#include <iostream>
#include <vector>
using namespace std;

// Checks if the given cell (r, c) can be visited
bool isSafe(vector<vector<char>> &grid, int r, int c, vector<vector<bool>> &visited)
{
    int n = grid.size();
    int m = grid[0].size();

    // Cell is within bounds, contains land ('L'), and is not yet visited
    return (r >= 0 && r < n && c >= 0 && c < m && grid[r][c] == 'L' && !visited[r][c]);
}

// Performs DFS to mark all connected land cells
void dfs(vector<vector<char>> &grid, int r, int c, vector<vector<bool>> &visited)
{
    // Mark current cell as visited
    visited[r][c] = true;

    // All 8 possible directions (vertical, horizontal, diagonal)
    vector<int> dr = {-1, -1, -1, 0, 0, 1, 1, 1};
    vector<int> dc = {-1, 0, 1, -1, 1, -1, 0, 1};

    // Explore all connected neighbours
    for (int k = 0; k < 8; k++)
    {
        int nr = r + dr[k];
        int nc = c + dc[k];

        if (isSafe(grid, nr, nc, visited))
            dfs(grid, nr, nc, visited);
    }
}

// finding number of distinct islands in the grid
int countIslands(vector<vector<char>> &grid)
{
    int n = grid.size();
    int m = grid[0].size();

    // Matrix to track visited cells
    vector<vector<bool>> visited(n, vector<bool>(m, false));

    int islands = 0;

    // Traverse every cell in the grid
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < m; j++)
        {
            // Start a new DFS when an unvisited land cell is found
            if (grid[i][j] == 'L' && !visited[i][j])
            {
                dfs(grid, i, j, visited);
                islands++;
            }
        }
    }

    return islands;
}

int main()
{
    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
class GFG {

    // Checks if the given cell (r, c) can be visited
    public static boolean isSafe(char[][] grid, int r, int c, boolean[][] visited) {

        int n = grid.length;
        int m = grid[0].length;

        // Cell is within bounds, contains land ('L'), and is not yet visited
        return (r >= 0 && r < n && c >= 0 && c < m &&
                grid[r][c] == 'L' && !visited[r][c]);
    }

    // Performs DFS to mark all connected land cells
    public static void dfs(char[][] grid, int r, int c, boolean[][] visited) {

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

        // All 8 possible directions (vertical, horizontal, diagonal)
        int[] dr = {-1, -1, -1, 0, 0, 1, 1, 1};
        int[] dc = {-1, 0, 1, -1, 1, -1, 0, 1};

        // Explore all connected neighbours
        for (int k = 0; k < 8; k++) {
            int nr = r + dr[k];
            int nc = c + dc[k];

            if (isSafe(grid, nr, nc, visited))
                dfs(grid, nr, nc, visited);
        }
    }

    // finding number of distinct islands in the grid
    public static int countIslands(char[][] grid) {

        int n = grid.length;
        int m = grid[0].length;

        // Matrix to track visited cells
        boolean[][] visited = new boolean[n][m];

        int islands = 0;

        // Traverse every cell in the grid
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {

                // Start a new DFS when an unvisited land cell is found
                if (grid[i][j] == 'L' && !visited[i][j]) {
                    dfs(grid, i, j, visited);
                    islands++;
                }
            }
        }

        return islands;
    }

    public static void main(String[] args) {

        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'}
        };

        System.out.println(countIslands(grid));
    }
}
Python
# Checks if the given cell (r, c) can be visited
def isSafe(grid, r, c, visited):
    n = len(grid)
    m = len(grid[0])

    # Cell is within bounds, contains land ('L'), and is not yet visited
    return (0 <= r < n and 0 <= c < m and grid[r][c] == 'L' and not visited[r][c])

# Performs DFS to mark all connected land cells
def dfs(grid, r, c, visited):
    
    # Mark current cell as visited
    visited[r][c] = True

    # All 8 possible directions (vertical, horizontal, diagonal)
    dr = [-1, -1, -1, 0, 0, 1, 1, 1]
    dc = [-1, 0, 1, -1, 1, -1, 0, 1]

    # Explore all connected neighbours
    for k in range(8):
        nr = r + dr[k]
        nc = c + dc[k]
        if isSafe(grid, nr, nc, visited):
            dfs(grid, nr, nc, visited)

# finding number of distinct islands in the grid
def countIslands(grid):
    n = len(grid)
    m = len(grid[0])

    # Matrix to track visited cells
    visited = [[False for _ in range(m)] for _ in range(n)]

    islands = 0

    # Traverse every cell in the grid
    for i in range(n):
        for j in range(m):
            # Start a new DFS when an unvisited land cell is found
            if grid[i][j] == 'L' and not visited[i][j]:
                dfs(grid, i, j, visited)
                islands += 1

    return islands

if __name__ == "__main__":
    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']
    ]

    # printing the number of islands
    print(countIslands(grid))
C#
using System;

class GFG
{
    // Checks if the given cell (r, c) can be visited
    public static bool isSafe(char[][] grid, int r, int c, bool[][] visited)
    {
        int n = grid.Length;
        int m = grid[0].Length;

        // Cell is within bounds, contains land ('L'), and is not yet visited
        return (r >= 0 && r < n && c >= 0 && c < m &&
                grid[r][c] == 'L' && !visited[r][c]);
    }

    // Performs DFS to mark all connected land cells
    public static void dfs(char[][] grid, int r, int c,
                           bool[][] visited)
    {
        // Mark current cell as visited
        visited[r][c] = true;

        // All 8 possible directions (vertical, horizontal, diagonal)
        int[] dr = {-1, -1, -1, 0, 0, 1, 1, 1};
        int[] dc = {-1, 0, 1, -1, 1, -1, 0, 1};

        // Explore all connected neighbours
        for (int k = 0; k < 8; k++)
        {
            int nr = r + dr[k];
            int nc = c + dc[k];

            if (isSafe(grid, nr, nc, visited))
                dfs(grid, nr, nc, visited);
        }
    }

    // finding number of distinct islands in the grid
    public static int countIslands(char[][] grid)
    {
        int n = grid.Length;
        int m = grid[0].Length;

        // Matrix to track visited cells
        bool[][] visited = new bool[n][];

        for (int i = 0; i < n; i++)
            visited[i] = new bool[m];

        int islands = 0;

        // Traverse every cell in the grid
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < m; j++)
            {
                // Start a new DFS when an unvisited land cell is found
                if (grid[i][j] == 'L' && !visited[i][j])
                {
                    dfs(grid, i, j, visited);
                    islands++;
                }
            }
        }

        return islands;
    }

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

        Console.WriteLine(countIslands(grid));
    }
}
JavaScript
// Checks if the given cell (r, c) can be visited
function isSafe(grid, r, c, visited) {
    const n = grid.length;
    const m = grid[0].length;

    // Cell is within bounds, contains land ('L'), and is not yet visited
    return (r >= 0 && r < n && c >= 0 && c < m && grid[r][c] === 'L' && !visited[r][c]);
}

// Performs DFS to mark all connected land cells
function dfs(grid, r, c, visited) {
    // Mark current cell as visited
    visited[r][c] = true;

    // All 8 possible directions (vertical, horizontal, diagonal)
    const dr = [-1, -1, -1, 0, 0, 1, 1, 1];
    const dc = [-1, 0, 1, -1, 1, -1, 0, 1];

    // Explore all connected neighbours
    for (let k = 0; k < 8; k++) {
        const nr = r + dr[k];
        const nc = c + dc[k];

        if (isSafe(grid, nr, nc, visited))
            dfs(grid, nr, nc, visited);
    }
}

// finding number of distinct islands in the grid
function countIslands(grid) {
    const n = grid.length;
    const m = grid[0].length;

    // Matrix to track visited cells
    const visited = Array.from({ length: n }, () => Array(m).fill(false));

    let islands = 0;

    // Traverse every cell in the grid
    for (let i = 0; i < n; i++) {
        for (let j = 0; j < m; j++) {
            
            // Start a new DFS when an unvisited land cell is found
            if (grid[i][j] === 'L' && !visited[i][j]) {
                dfs(grid, i, j, visited);
                islands++;
            }
        }
    }

    return islands;
}

// Driver code
const 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']
];

// printing the number of islands
console.log(countIslands(grid));

Output
4

Using Breadth First Search - O(n x m) time and O(n x m) space

Traverse the grid and whenever an unvisited 'L' is found, treat it as a new island and use BFS to visit all land cells connected to it in all 8 directions. A separate visited matrix is used to avoid modifying the original grid.

  • Create a visited matrix of size n × m.
  • Traverse every cell of the grid.
  • If an unvisited 'L' is found, increment the island count.
  • Add the cell to a queue and mark it as visited.
  • Remove a cell from the queue and check all 8 directions.
  • Add every valid, unvisited land cell to the queue and mark it visited.
  • Continue until the queue becomes empty.
  • Repeat for the remaining cells and return the island count.

Consider the grid:

file
  • Start BFS from (0,0) -> islands = 1; visit (0,1) and (1,1).
  • Start BFS from (1,4) -> islands = 2; visit (2,3) and (2,4).
  • Start BFS from (2,0) -> islands = 3.
  • Start BFS from (4,0) -> islands = 4.
  • The remaining connected land cells (4,2) and (4,3) are visited in the same BFS.
  • No unvisited land remains.

Therefore: Number of islands = 4

C++
#include <iostream>
#include <vector>
#include <queue>
using namespace std;

// Check if the cell (r, c) is valid for BFS traversal
// It must lie within grid bounds, contain land ('L'), and not be visited yet
bool isSafe(vector<vector<char>>& grid, int r, int c, vector<vector<bool>>& visited) {
    int n = grid.size();
    int m = grid[0].size();
    return (r >= 0 && r < n && c >= 0 && c < m && grid[r][c] == 'L' && !visited[r][c]);
}

void bfs(vector<vector<char>>& grid, vector<vector<bool>>& visited, int startR, int startC) {
    
    // Possible 8 directions (vertical, horizontal, and diagonal)
    vector<int> dRow = {-1, -1, -1, 0, 0, 1, 1, 1};
    vector<int> dCol = {-1, 0, 1, -1, 1, -1, 0, 1};

    queue<pair<int, int>> q;
    q.push({startR, startC});
    visited[startR][startC] = true;

    // Explore all reachable land cells for this island
    while (!q.empty()) {
        auto [r, c] = q.front();
        q.pop();

        // Check all 8 neighbors of the current cell
        for (int k = 0; k < 8; k++) {
            int newR = r + dRow[k];
            int newC = c + dCol[k];
            if (isSafe(grid, newR, newC, visited)) {
                visited[newR][newC] = true;
                q.push({newR, newC});
            }
        }
    }
}

// Count the total number of islands in the grid
int countIslands(vector<vector<char>>& grid) {
    int n = grid.size();
    int m = grid[0].size();
    vector<vector<bool>> visited(n, vector<bool>(m, false));
    int islandCount = 0;

    // Traverse every cell in the grid
    for (int r = 0; r < n; r++) {
        for (int c = 0; c < m; c++) {

            // If an unvisited land cell is found, start BFS for that island
            if (grid[r][c] == 'L' && !visited[r][c]) {
                bfs(grid, visited, r, c);
                islandCount++;
            }
        }
    }

    return islandCount;
}

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
import java.util.Queue;
import java.util.LinkedList;

class GFG {

    // Check if the cell (r, c) is valid for BFS traversal
    // It must lie within grid bounds, contain land ('L'), and not be visited yet
    public static boolean isSafe(char[][] grid, int r, int c, boolean[][] visited) {
        int n = grid.length;
        int m = grid[0].length;
        return (r >= 0 && r < n && c >= 0 && c < m && grid[r][c] == 'L' && !visited[r][c]);
    }

    public static void bfs(char[][] grid, boolean[][] visited, int startR, int startC) {
        
        // Possible 8 directions (vertical, horizontal, and diagonal)
        int[] dRow = {-1, -1, -1, 0, 0, 1, 1, 1};
        int[] dCol = {-1, 0, 1, -1, 1, -1, 0, 1};

        Queue<int[]> q = new LinkedList<>();
        q.add(new int[]{startR, startC});
        visited[startR][startC] = true;

        // Explore all reachable land cells for this island
        while (!q.isEmpty()) {
            int[] cell = q.poll();
            int r = cell[0];
            int c = cell[1];

            // Check all 8 neighbors of the current cell
            for (int k = 0; k < 8; k++) {
                int newR = r + dRow[k];
                int newC = c + dCol[k];
                if (isSafe(grid, newR, newC, visited)) {
                    visited[newR][newC] = true;
                    q.add(new int[]{newR, newC});
                }
            }
        }
    }

    // Count the total number of islands in the grid
    public static int countIslands(char[][] grid) {
        int n = grid.length;
        int m = grid[0].length;
        boolean[][] visited = new boolean[n][m];
        int islandCount = 0;

        // Traverse every cell in the grid
        for (int r = 0; r < n; r++) {
            for (int c = 0; c < m; c++) {

                // If an unvisited land cell is found, start BFS for that island
                if (grid[r][c] == 'L' && !visited[r][c]) {
                    bfs(grid, visited, r, c);
                    islandCount++;
                }
            }
        }

        return islandCount;
    }

    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
from collections import deque

# Check if the cell (r, c) is valid for BFS traversal
# It must lie within grid bounds, contain land ('L'), and not be visited yet
def isSafe(grid, r, c, visited):
    n = len(grid)
    m = len(grid[0])
    return (0 <= r < n and 0 <= c < m and grid[r][c] == 'L' and not visited[r][c])

def bfs(grid, visited, startR, startC):
    
    # Possible 8 directions (vertical, horizontal, and diagonal)
    dRow = [-1, -1, -1, 0, 0, 1, 1, 1]
    dCol = [-1, 0, 1, -1, 1, -1, 0, 1]

    q = deque()
    q.append((startR, startC))
    visited[startR][startC] = True

    # Explore all reachable land cells for this island
    while q:
        r, c = q.popleft()

        # Check all 8 neighbors of the current cell
        for k in range(8):
            newR = r + dRow[k]
            newC = c + dCol[k]
            if isSafe(grid, newR, newC, visited):
                visited[newR][newC] = True
                q.append((newR, newC))

# Count the total number of islands in the grid
def countIslands(grid):
    n = len(grid)
    m = len(grid[0])
    visited = [[False] * m for _ in range(n)]
    islandCount = 0

    # Traverse every cell in the grid
    for r in range(n):
        for c in range(m):

            # If an unvisited land cell is found, start BFS for that island
            if grid[r][c] == 'L' and not visited[r][c]:
                bfs(grid, visited, r, c)
                islandCount += 1

    return islandCount


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#
using System;
using System.Collections.Generic;

class GFG
{
    // Check if the cell (r, c) is valid for BFS traversal
    // It must lie within grid bounds, contain land ('L'), and not be visited yet
    public static bool isSafe(char[][] grid, int r, int c,
                              bool[][] visited)
    {
        int n = grid.Length;
        int m = grid[0].Length;

        return (r >= 0 && r < n &&
                c >= 0 && c < m &&
                grid[r][c] == 'L' &&
                !visited[r][c]);
    }

    public static void bfs(char[][] grid, bool[][] visited,
                           int startR, int startC)
    {
        // Possible 8 directions (vertical, horizontal, and diagonal)
        int[] dRow = {-1, -1, -1, 0, 0, 1, 1, 1};
        int[] dCol = {-1, 0, 1, -1, 1, -1, 0, 1};

        Queue<(int, int)> q = new Queue<(int, int)>();

        q.Enqueue((startR, startC));
        visited[startR][startC] = true;

        // Explore all reachable land cells for this island
        while (q.Count > 0)
        {
            var current = q.Dequeue();

            int r = current.Item1;
            int c = current.Item2;

            // Check all 8 neighbors of the current cell
            for (int k = 0; k < 8; k++)
            {
                int newR = r + dRow[k];
                int newC = c + dCol[k];

                if (isSafe(grid, newR, newC, visited))
                {
                    visited[newR][newC] = true;
                    q.Enqueue((newR, newC));
                }
            }
        }
    }

    // Count the total number of islands in the grid
    public static int countIslands(char[][] grid)
    {
        int n = grid.Length;
        int m = grid[0].Length;

        bool[][] visited = new bool[n][];

        for (int i = 0; i < n; i++)
            visited[i] = new bool[m];

        int islandCount = 0;

        // Traverse every cell in the grid
        for (int r = 0; r < n; r++)
        {
            for (int c = 0; c < m; c++)
            {
                // If an unvisited land cell is found, start BFS for that island
                if (grid[r][c] == 'L' && !visited[r][c])
                {
                    bfs(grid, visited, r, c);
                    islandCount++;
                }
            }
        }

        return islandCount;
    }

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

        Console.WriteLine(countIslands(grid));
    }
}
JavaScript
// Check if the cell (r, c) is valid for BFS traversal
// It must lie within grid bounds, contain land ('L'), and not be visited yet
function isSafe(grid, r, c, visited) {
    const n = grid.length;
    const m = grid[0].length;
    return (r >= 0 && r < n && c >= 0 && c < m && grid[r][c] === 'L' && !visited[r][c]);
}

function bfs(grid, visited, startR, startC) {
    
    // Possible 8 directions (vertical, horizontal, and diagonal)
    const dRow = [-1, -1, -1, 0, 0, 1, 1, 1];
    const dCol = [-1, 0, 1, -1, 1, -1, 0, 1];

    const q = [];
    q.push([startR, startC]);
    visited[startR][startC] = true;

    // Explore all reachable land cells for this island
    while (q.length > 0) {
        const [r, c] = q.shift();

        // Check all 8 neighbors of the current cell
        for (let k = 0; k < 8; k++) {
            const newR = r + dRow[k];
            const newC = c + dCol[k];
            if (isSafe(grid, newR, newC, visited)) {
                visited[newR][newC] = true;
                q.push([newR, newC]);
            }
        }
    }
}

// Count the total number of islands in the grid
function countIslands(grid) {
    const n = grid.length;
    const m = grid[0].length;
    const visited = Array.from({ length: n }, () => Array(m).fill(false));
    let islandCount = 0;

    // Traverse every cell in the grid
    for (let r = 0; r < n; r++) {
        for (let c = 0; c < m; c++) {

            // If an unvisited land cell is found, start BFS for that island
            if (grid[r][c] === 'L' && !visited[r][c]) {
                bfs(grid, visited, r, c);
                islandCount++;
            }
        }
    }

    return islandCount;
}

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

Using Disjoint Set - O(n x m) time and O(n x m) space

Model the grid as a graph where each land cell is a node. Initially, every land cell belongs to its own set. For each land cell, check all 8 directions and merge it with any connected land cell. Finally, the number of unique sets gives the number of islands.

  • Create a DSU structure where every cell initially has itself as its parent.
  • Convert each cell (r, c) into a unique index using r * m + c.
  • Traverse every cell of the grid.
  • For each land cell 'L', check all 8 neighboring cells.
  • If a neighboring cell is also 'L', merge both cells using unite().
  • After all cells are processed, find the parent of every land cell.
  • Store the parents in a HashSet to remove duplicates.
  • The size of the set is the total number of islands.
C++
#include <bits/stdc++.h>
using namespace std;

// Find the parent of a cell
int find(int x, vector<int>& parent) {
    if (parent[x] != x)
        parent[x] = find(parent[x], parent);

    return parent[x];
}

// Join two connected cells
void unite(int x, int y, vector<int>& parent, vector<int>& rank) {
    x = find(x, parent);
    y = find(y, parent);

    if (x == y)
        return;

    if (rank[x] < rank[y])
        parent[x] = y;
    else if (rank[x] > rank[y])
        parent[y] = x;
    else {
        parent[y] = x;
        rank[x]++;
    }
}

int countIslands(vector<vector<char>>& grid) {
    int n = grid.size();
    int m = grid[0].size();

    // Initially, every cell belongs to its own group
    vector<int> parent(n * m);
    vector<int> rank(n * m, 0);

    for (int i = 0; i < n * m; i++)
        parent[i] = i;

    // 8 possible directions
    int dr[] = {-1, -1, -1, 0, 0, 1, 1, 1};
    int dc[] = {-1, 0, 1, -1, 1, -1, 0, 1};

    // Join connected land cells
    for (int r = 0; r < n; r++) {
        for (int c = 0; c < m; c++) {

            if (grid[r][c] != 'L')
                continue;

            int current = r * m + c;

            for (int k = 0; k < 8; k++) {
                int nr = r + dr[k];
                int nc = c + dc[k];

                if (nr >= 0 && nr < n &&
                    nc >= 0 && nc < m &&
                    grid[nr][nc] == 'L') {

                    int next = nr * m + nc;
                    unite(current, next, parent, rank);
                }
            }
        }
    }

    // Count unique island groups
    unordered_set<int> islands;

    for (int r = 0; r < n; r++) {
        for (int c = 0; c < m; c++) {

            if (grid[r][c] == 'L') {
                int cell = r * m + c;
                islands.insert(find(cell, parent));
            }
        }
    }

    return islands.size();
}

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
import java.util.HashSet;

// Find the parent of a cell
public static int find(int x, int[] parent) {
    if (parent[x] != x)
        parent[x] = find(parent[x], parent);

    return parent[x];
}

// Join two connected cells
public static void unite(int x, int y, int[] parent, int[] rank) {
    x = find(x, parent);
    y = find(y, parent);

    if (x == y)
        return;

    if (rank[x] < rank[y])
        parent[x] = y;
    else if (rank[x] > rank[y])
        parent[y] = x;
    else {
        parent[y] = x;
        rank[x]++;
    }
}

public static int countIslands(char[][] grid) {
    int n = grid.length;
    int m = grid[0].length;

    // Initially, every cell belongs to its own group
    int[] parent = new int[n * m];
    int[] rank = new int[n * m];

    for (int i = 0; i < n * m; i++)
        parent[i] = i;

    // 8 possible directions
    int[] dr = {-1, -1, -1, 0, 0, 1, 1, 1};
    int[] dc = {-1, 0, 1, -1, 1, -1, 0, 1};

    // Join connected land cells
    for (int r = 0; r < n; r++) {
        for (int c = 0; c < m; c++) {

            if (grid[r][c] != 'L')
                continue;

            int current = r * m + c;

            for (int k = 0; k < 8; k++) {
                int nr = r + dr[k];
                int nc = c + dc[k];

                if (nr >= 0 && nr < n &&
                    nc >= 0 && nc < m &&
                    grid[nr][nc] == 'L') {

                    int next = nr * m + nc;
                    unite(current, next, parent, rank);
                }
            }
        }
    }

    // Count unique island groups
    HashSet<Integer> islands = new HashSet<>();

    for (int r = 0; r < n; r++) {
        for (int c = 0; c < m; c++) {

            if (grid[r][c] == 'L') {
                int cell = r * m + c;
                islands.add(find(cell, parent));
            }
        }
    }

    return islands.size();
}

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
# Find the parent of a cell
def find(x, parent):
    if parent[x] != x:
        parent[x] = find(parent[x], parent)

    return parent[x]


# Join two connected cells
def unite(x, y, parent, rank):
    x = find(x, parent)
    y = find(y, parent)

    if x == y:
        return

    if rank[x] < rank[y]:
        parent[x] = y
    elif rank[x] > rank[y]:
        parent[y] = x
    else:
        parent[y] = x
        rank[x] += 1


def countIslands(grid):
    n = len(grid)
    m = len(grid[0])

    # Initially, every cell belongs to its own group
    parent = list(range(n * m))
    rank = [0] * (n * m)

    # 8 possible directions
    dr = [-1, -1, -1, 0, 0, 1, 1, 1]
    dc = [-1, 0, 1, -1, 1, -1, 0, 1]

    # Join connected land cells
    for r in range(n):
        for c in range(m):

            if grid[r][c] != 'L':
                continue

            current = r * m + c

            for k in range(8):
                nr = r + dr[k]
                nc = c + dc[k]

                if (nr >= 0 and nr < n and
                    nc >= 0 and nc < m and
                    grid[nr][nc] == 'L'):

                    next = nr * m + nc
                    unite(current, next, parent, rank)

    # Count unique island groups
    islands = set()

    for r in range(n):
        for c in range(m):

            if grid[r][c] == 'L':
                cell = r * m + c
                islands.add(find(cell, parent))

    return len(islands)


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#
using System;
using System.Collections.Generic;

class GFG
{
    // Find the parent of a cell
    public static int find(int x, int[] parent)
    {
        if (parent[x] != x)
            parent[x] = find(parent[x], parent);

        return parent[x];
    }

    // Join two connected cells
    public static void unite(int x, int y, int[] parent, int[] rank)
    {
        x = find(x, parent);
        y = find(y, parent);

        if (x == y)
            return;

        if (rank[x] < rank[y])
            parent[x] = y;
        else if (rank[x] > rank[y])
            parent[y] = x;
        else
        {
            parent[y] = x;
            rank[x]++;
        }
    }

    public static int countIslands(char[][] grid)
    {
        int n = grid.Length;
        int m = grid[0].Length;

        // Initially, every cell belongs to its own group
        int[] parent = new int[n * m];
        int[] rank = new int[n * m];

        for (int i = 0; i < n * m; i++)
            parent[i] = i;

        // 8 possible directions
        int[] dr = {-1, -1, -1, 0, 0, 1, 1, 1};
        int[] dc = {-1, 0, 1, -1, 1, -1, 0, 1};

        // Join connected land cells
        for (int r = 0; r < n; r++)
        {
            for (int c = 0; c < m; c++)
            {
                if (grid[r][c] != 'L')
                    continue;

                int current = r * m + c;

                for (int k = 0; k < 8; k++)
                {
                    int nr = r + dr[k];
                    int nc = c + dc[k];

                    if (nr >= 0 && nr < n &&
                        nc >= 0 && nc < m &&
                        grid[nr][nc] == 'L')
                    {
                        int next = nr * m + nc;
                        unite(current, next, parent, rank);
                    }
                }
            }
        }

        // Count unique island groups
        HashSet<int> islands = new HashSet<int>();

        for (int r = 0; r < n; r++)
        {
            for (int c = 0; c < m; c++)
            {
                if (grid[r][c] == 'L')
                {
                    int cell = r * m + c;
                    islands.Add(find(cell, parent));
                }
            }
        }

        return islands.Count;
    }

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

        Console.WriteLine(countIslands(grid));
    }
}
JavaScript
// Find the parent of a cell
function find(x, parent) {
    if (parent[x] !== x)
        parent[x] = find(parent[x], parent);

    return parent[x];
}

// Join two connected cells
function unite(x, y, parent, rank) {
    x = find(x, parent);
    y = find(y, parent);

    if (x === y)
        return;

    if (rank[x] < rank[y])
        parent[x] = y;
    else if (rank[x] > rank[y])
        parent[y] = x;
    else {
        parent[y] = x;
        rank[x]++;
    }
}

function countIslands(grid) {
    let n = grid.length;
    let m = grid[0].length;

    // Initially, every cell belongs to its own group
    let parent = new Array(n * m);
    let rank = new Array(n * m).fill(0);

    for (let i = 0; i < n * m; i++)
        parent[i] = i;

    // 8 possible directions
    let dr = [-1, -1, -1, 0, 0, 1, 1, 1];
    let dc = [-1, 0, 1, -1, 1, -1, 0, 1];

    // Join connected land cells
    for (let r = 0; r < n; r++) {
        for (let c = 0; c < m; c++) {

            if (grid[r][c] !== 'L')
                continue;

            let current = r * m + c;

            for (let k = 0; k < 8; k++) {
                let nr = r + dr[k];
                let nc = c + dc[k];

                if (nr >= 0 && nr < n &&
                    nc >= 0 && nc < m &&
                    grid[nr][nc] === 'L') {

                    let next = nr * m + nc;
                    unite(current, next, parent, rank);
                }
            }
        }
    }

    // Count unique island groups
    let islands = new Set();

    for (let r = 0; r < n; r++) {
        for (let c = 0; c < m; c++) {

            if (grid[r][c] === 'L') {
                let cell = r * m + c;
                islands.add(find(cell, parent));
            }
        }
    }

    return islands.size;
}

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));

Output
4
Comment