Open In App

Number of Islands

Last Updated : 30 Oct, 2025
Suggest changes
Share
188 Likes
Like
Report

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

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

The main idea is to explore each land cell ('L') using DFS and mark all connected land cells that belong to the same island. To avoid modifying the original grid, we maintain a separate visited matrix that keeps track of which cells have already been explored. The DFS explores all 8 possible directions (up, down, left, right, and 4 diagonals), marking every connected 'L' cell as visited. This ensures that all parts of the current island are counted once.
Each time we encounter an unvisited land cell, it represents the start of a new island, and we perform DFS to mark all cells of that island. By the end, the total count represents the number of distinct islands in the grid.

C++
//Driver Code Starts
#include <iostream>
#include <vector>
using namespace std;

//Driver Code Ends

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

//Driver Code Starts

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

    // printing the number of islands
    cout << countIslands(grid) << endl;

    return 0;
}

//Driver Code Ends
Java
//Driver Code Starts
import java.util.*;

public class Main {

//Driver Code Ends

    // Checks if the given cell (r, c) can be visited
    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
    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
    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;
    }

//Driver Code Starts

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

        // printing the number of islands
        System.out.println(countIslands(grid));
    }
}

//Driver Code Ends
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


#Driver Code Starts
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))

#Driver Code Ends
C#
//Driver Code Starts
using System;
using System.Collections.Generic;

class Program
{
//Driver Code Ends

    // Checks if the given cell (r, c) can be visited
    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
    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
    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;
    }

//Driver Code Starts

    static void Main()
    {
        char[][] grid = new char[][]
        {
            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'}
        };

        // printing the number of islands
        Console.WriteLine(CountIslands(grid));
    }
}

//Driver Code Ends
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 Starts
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));

//Driver Code Ends

Output
4

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

The idea is to use Breadth First Search (BFS) to explore all connected land cells for each island. We traverse the entire grid, and whenever we encounter an unvisited land cell ('L'), we perform a BFS starting from that cell to explore its entire connected component. During BFS, we visit all cells connected horizontally, vertically, or diagonally to the current land cell.
To ensure we don’t revisit the same cell multiple times, we maintain a separate boolean matrix to mark visited cells instead of modifying the original grid. Each BFS traversal explores one complete island, after which we increment the island counter. Repeating this for all cells ensures that every island is counted exactly once, and the final counter gives the total number of islands in the grid.

C++
//Driver Code Starts
#include <iostream>
#include <vector>
#include <queue>
using namespace std;

//Driver Code Ends

// 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]);
}

// Perform BFS to traverse all connected land cells (forming one island)
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;
}

//Driver Code Starts

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

//Driver Code Ends
Java
//Driver Code Starts
import java.util.*;

public class Main {

//Driver Code Ends

    // 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
    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]);
    }

    // Perform BFS to traverse all connected land cells (forming one island)
    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
    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;
    }

//Driver Code Starts

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

//Driver Code Ends
Python
#Driver Code Starts
from collections import deque

#Driver Code Ends

# 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])

# Perform BFS to traverse all connected land cells (forming one island)
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

#Driver Code Starts


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

#Driver Code Ends
C#
//Driver Code Starts
using System;
using System.Collections.Generic;

class Program
{
//Driver Code Ends

    // 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
    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]);
    }

    // Perform BFS to traverse all connected land cells (forming one island)
    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 (r, c) = q.Dequeue();

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

//Driver Code Starts

    static void Main()
    {
        char[][] grid = new char[][]
        {
            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));
    }
}

//Driver Code Ends
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]);
}

// Perform BFS to traverse all connected land cells (forming one island)
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;
}


//Driver Code Starts
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));

//Driver Code Ends

Output
4

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

The idea is to model the grid as a graph where each land cell acts as a node. Using the Disjoint Set (Union-Find) structure, we initially treat every land cell as its own parent.
Then, for each land cell, we check all eight neighboring directions — if a neighbor is also land, we perform a union operation to merge their sets.
After all unions are done, each unique parent in the Disjoint Set represents one distinct island.
Counting these unique parents gives the total number of islands in the grid.

C++
//Driver Code Starts
#include <iostream>
#include <vector>
#include <unordered_set>
using namespace std;

//Driver Code Ends

// Disjoint Set Union (Union-Find) class
class DisjointSet {
    vector<int> parent, rank;

public:
    // Initialize DSU with each node as its own parent
    DisjointSet(int n) {
        parent.resize(n);
        rank.assign(n, 0);
        for (int i = 0; i < n; i++)
            parent[i] = i;
    }

    // Find operation with path compression
    int find(int x) {
        if (parent[x] != x)
            parent[x] = find(parent[x]);
        return parent[x];
    }

    // Union operation by rank
    void unite(int x, int y) {
        int xRoot = find(x);
        int yRoot = find(y);

        if (xRoot == yRoot)
            return;

        if (rank[xRoot] < rank[yRoot])
            parent[xRoot] = yRoot;
        else if (rank[yRoot] < rank[xRoot])
            parent[yRoot] = xRoot;
        else {
            parent[yRoot] = xRoot;
            rank[xRoot]++;
        }
    }
};

// Count total islands in the grid using DSU
int countIslands(vector<vector<char>>& grid) {
    int n = grid.size();
    int m = grid[0].size();
    DisjointSet ds(n * m);

    // Directions for 8-connected neighbors
    vector<pair<int, int>> directions = {
        {-1, 0}, {1, 0}, {0, -1}, {0, 1},
        {-1, -1}, {-1, 1}, {1, -1}, {1, 1}
    };

    auto getIndex = [&](int r, int c) {
        return r * m + c;
    };

    // Perform union for all connected 'L' (land) cells
    for (int r = 0; r < n; r++) {
        for (int c = 0; c < m; c++) {
            if (grid[r][c] == 'L') {
                for (auto [dr, dc] : directions) {
                    int nr = r + dr, nc = c + dc;
                    if (nr >= 0 && nr < n && nc >= 0 && nc < m && grid[nr][nc] == 'L')
                        ds.unite(getIndex(r, c), getIndex(nr, nc));
                }
            }
        }
    }

    // Use a set to count unique root parents representing islands
    unordered_set<int> uniqueIslands;
    for (int r = 0; r < n; r++) {
        for (int c = 0; c < m; c++) {
            if (grid[r][c] == 'L')
                uniqueIslands.insert(ds.find(getIndex(r, c)));
        }
    }

    return uniqueIslands.size();
}

//Driver Code Starts

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

//Driver Code Ends
Java
//Driver Code Starts
import java.util.*;

//Driver Code Ends

class DisjointSet {
    private int[] parent;
    private int[] rank;

    // Initialize DSU with each node as its own parent
    public DisjointSet(int n)
    {
        parent = new int[n];
        rank = new int[n];
        for (int i = 0; i < n; i++)
            parent[i] = i;
    }

    // Find operation with path compression
    public int find(int x)
    {
        if (parent[x] != x)
            parent[x] = find(parent[x]);
        return parent[x];
    }

    // Union operation by rank
    public void unite(int x, int y)
    {
        int xRoot = find(x);
        int yRoot = find(y);

        if (xRoot == yRoot)
            return;

        if (rank[xRoot] < rank[yRoot])
            parent[xRoot] = yRoot;
        else if (rank[yRoot] < rank[xRoot])
            parent[yRoot] = xRoot;
        else {
            parent[yRoot] = xRoot;
            rank[xRoot]++;
        }
    }
}

// Count total islands in the grid using DSU
public class Main {
    public static int countIslands(char[][] grid)
    {
        int n = grid.length;
        int m = grid[0].length;
        DisjointSet ds = new DisjointSet(n * m);

        // Directions for 8-connected neighbors
        int[][] directions = { { -1, 0 },  { 1, 0 },
                               { 0, -1 },  { 0, 1 },
                               { -1, -1 }, { -1, 1 },
                               { 1, -1 },  { 1, 1 } };

        // Perform union for all connected 'L' (land) cells
        for (int r = 0; r < n; r++) {
            for (int c = 0; c < m; c++) {
                if (grid[r][c] == 'L') {
                    for (int[] dir : directions) {
                        int nr = r + dir[0], nc
                                             = c + dir[1];
                        if (nr >= 0 && nr < n && nc >= 0
                            && nc < m
                            && grid[nr][nc] == 'L')
                            ds.unite(r * m + c,
                                     nr * m + nc);
                    }
                }
            }
        }

        // Use a set to count unique root parents
        // representing islands
        Set<Integer> uniqueIslands = new HashSet<>();
        for (int r = 0; r < n; r++) {
            for (int c = 0; c < m; c++) {
                if (grid[r][c] == 'L')
                    uniqueIslands.add(ds.find(r * m + c));
            }
        }

        return uniqueIslands.size();
    }

//Driver Code Starts

    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));
    }
}
//Driver Code Ends
Python
class DisjointSet:
    # Initialize DSU with each node as its own parent
    def __init__(self, n):
        self.parent = list(range(n))
        self.rank = [0] * n

    # Find operation with path compression
    def find(self, x):
        if self.parent[x] != x:
            self.parent[x] = self.find(self.parent[x])
        return self.parent[x]

    # Union operation by rank
    def unite(self, x, y):
        xRoot = self.find(x)
        yRoot = self.find(y)
        if xRoot == yRoot:
            return
        if self.rank[xRoot] < self.rank[yRoot]:
            self.parent[xRoot] = yRoot
        elif self.rank[yRoot] < self.rank[xRoot]:
            self.parent[yRoot] = xRoot
        else:
            self.parent[yRoot] = xRoot
            self.rank[xRoot] += 1


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

    # Directions for 8-connected neighbors
    directions = [
        (-1, 0), (1, 0), (0, -1), (0, 1),
        (-1, -1), (-1, 1), (1, -1), (1, 1)
    ]

    # Perform union for all connected 'L' (land) cells
    for r in range(n):
        for c in range(m):
            if grid[r][c] == 'L':
                for dr, dc in directions:
                    nr, nc = r + dr, c + dc
                    if 0 <= nr < n and 0 <= nc < m and grid[nr][nc] == 'L':
                        ds.unite(r * m + c, nr * m + nc)

    # Use a set to count unique root parents representing islands
    uniqueIslands = set()
    for r in range(n):
        for c in range(m):
            if grid[r][c] == 'L':
                uniqueIslands.add(ds.find(r * m + c))

    return len(uniqueIslands)



#Driver Code Starts
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))

#Driver Code Ends
C#
//Driver Code Starts
using System;
using System.Collections.Generic;

//Driver Code Ends

class DisjointSet {
    private int[] parent;
    private int[] rank;

    // Initialize DSU with each node as its own parent
    public DisjointSet(int n)
    {
        parent = new int[n];
        rank = new int[n];
        for (int i = 0; i < n; i++)
            parent[i] = i;
    }

    // Find operation with path compression
    public int Find(int x)
    {
        if (parent[x] != x)
            parent[x] = Find(parent[x]);
        return parent[x];
    }

    // Union operation by rank
    public void Unite(int x, int y)
    {
        int xRoot = Find(x);
        int yRoot = Find(y);
        if (xRoot == yRoot)
            return;
        if (rank[xRoot] < rank[yRoot])
            parent[xRoot] = yRoot;
        else if (rank[yRoot] < rank[xRoot])
            parent[yRoot] = xRoot;
        else {
            parent[yRoot] = xRoot;
            rank[xRoot]++;
        }
    }
}

class Program {
    // Count total islands in the grid using DSU
    static int CountIslands(char[][] grid)
    {
        int n = grid.Length;
        int m = grid[0].Length;
        DisjointSet ds = new DisjointSet(n * m);

        // Directions for 8-connected neighbors
        int[][] directions
            = { new int[] { -1, 0 },  new int[] { 1, 0 },
                new int[] { 0, -1 },  new int[] { 0, 1 },
                new int[] { -1, -1 }, new int[] { -1, 1 },
                new int[] { 1, -1 },  new int[] { 1, 1 } };

        // Perform union for all connected 'L' (land) cells
        for (int r = 0; r < n; r++) {
            for (int c = 0; c < m; c++) {
                if (grid[r][c] == 'L') {
                    foreach(var dir in directions)
                    {
                        int nr = r + dir[0], nc
                                             = c + dir[1];
                        if (nr >= 0 && nr < n && nc >= 0
                            && nc < m
                            && grid[nr][nc] == 'L')
                            ds.Unite(r * m + c,
                                     nr * m + nc);
                    }
                }
            }
        }

        // Use a set to count unique root parents
        // representing islands
        HashSet<int> uniqueIslands = new HashSet<int>();
        for (int r = 0; r < n; r++) {
            for (int c = 0; c < m; c++) {
                if (grid[r][c] == 'L')
                    uniqueIslands.Add(ds.Find(r * m + c));
            }
        }

        return uniqueIslands.Count;
    }

//Driver Code Starts

    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));
    }
}
//Driver Code Ends
JavaScript
class DisjointSet {
    constructor(n)
    {
        this.parent = Array.from({length : n}, (_, i) => i);
        this.rank = new Array(n).fill(0);
    }

    // Find operation with path compression
    find(x)
    {
        if (this.parent[x] !== x)
            this.parent[x] = this.find(this.parent[x]);
        return this.parent[x];
    }

    // Union operation by rank
    unite(x, y)
    {
        let xRoot = this.find(x);
        let yRoot = this.find(y);
        if (xRoot === yRoot)
            return;

        if (this.rank[xRoot] < this.rank[yRoot]) {
            this.parent[xRoot] = yRoot;
        }
        else if (this.rank[yRoot] < this.rank[xRoot]) {
            this.parent[yRoot] = xRoot;
        }
        else {
            this.parent[yRoot] = xRoot;
            this.rank[xRoot]++;
        }
    }
}

// Count total islands in the grid using DSU
function countIslands(grid)
{
    let n = grid.length;
    let m = grid[0].length;
    let ds = new DisjointSet(n * m);

    // Directions for 8-connected neighbors
    let directions = [
        [ -1, 0 ], [ 1, 0 ], [ 0, -1 ], [ 0, 1 ],
        [ -1, -1 ], [ -1, 1 ], [ 1, -1 ], [ 1, 1 ]
    ];

    // Perform union for all connected 'L' (land) cells
    for (let r = 0; r < n; r++) {
        for (let c = 0; c < m; c++) {
            if (grid[r][c] === "L") {
                for (let [dr, dc] of directions) {
                    let nr = r + dr, nc = c + dc;
                    if (nr >= 0 && nr < n && nc >= 0
                        && nc < m && grid[nr][nc] === "L")
                        ds.unite(r * m + c, nr * m + nc);
                }
            }
        }
    }

    // Use a set to count unique root parents representing
    // islands
    let uniqueIslands = new Set();
    for (let r = 0; r < n; r++) {
        for (let c = 0; c < m; c++) {
            if (grid[r][c] === "L")
                uniqueIslands.add(ds.find(r * m + c));
        }
    }

    return uniqueIslands.size;
}


//Driver Code Starts
// Example usage
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));
//Driver Code Ends

Output
4



Explore