Open In App

Number of Islands in a Circular Matrix

Last Updated : 06 Dec, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given a 2D Matrix world map[][] of size N * M, such that all the places covered via land are represented by ‘L’ and the rest by ‘W’. Since the world is spherical rows and columns are cyclic (before row 1 row n comes and after row n row 1 same for the column). Count the number of islands.

Examples:

Input: N = 4, M = 4, worldMap = [ [‘L’, ‘W’, ‘W’, ‘L’] , [‘L’, ‘W, ‘W’, ‘L’] , [‘L’, ‘W’, ‘W’, ‘L’] , [‘L’, ‘W’, ‘W’, ‘L’] ]
Output: 1
Explanation: Since the map is circular, all the lands are connected to form 1 Island.

Islands

Input: N = 3, M = 3, worldMap = [ [‘W’, ‘W’, ‘W’] , [‘W’, ‘L’, ‘W’,] , [‘W’, ‘W’, ‘W’] ]
Output: 1
Explanation: There is just 1 island covered by water.

Approach: The problem can be solved using the following approach:

The approach is to use DFS to count islands on a world map grid, considering the map’s cyclic nature. Start from an unvisited land cell, it explores adjacent cells while cyclically wrapping around the map. Whenever we move outside the matrix, then we can simply modulo the row and column with the total number of rows and columns respectively to land inside the matrix. Instead of using another matrix to count the visited lands, we can simply change the visited land to water.

Steps to solve the problem:

  • Declare a function dfs() to start a DFS from an unvisited land cell.
  • Explore all the land cells connected with this cell.
  • While exploring a land cell, turn the land cell to water cell so that no cell is counted twice.
  • If at any point we move outside the grid, simply modulo the row and column with the total number of rows and columns respectively.
  • After the DFS gets completed, if we encounter any unvisited land cell, then increment the count of islands by 1 and again start a DFS from this cell.
  • Finally, return the number of islands.

Below is the implementation of the approach:

C++




// C++ Code for the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Define possible directions to move
vector<pair<int, int> > directions
    = { { -1, 0 }, { 1, 0 }, { 0, -1 }, { 0, 1 } };
void dfs(vector<vector<char> >& worldMap, int row, int col,
         int rows, int cols)
{
    // Mark the current cell as visited
    worldMap[row][col] = 'W';
 
    // Explore all adjacent cells, including
    // cyclically wrapping around the map
    for (const auto& dir : directions) {
 
        // Cyclically wrap around if needed
        int new_row = (row + dir.first + rows) % rows;
        int new_col = (col + dir.second + cols) % cols;
 
        // Check if the adjacent cell is unvisited
        if (worldMap[new_row][new_col] == 'L') {
            // Recursively explore adjacent cells
            dfs(worldMap, new_row, new_col, rows, cols);
        }
    }
}
 
int countIslandsOnMap(vector<vector<char> >& worldMap)
{
 
    int rows = worldMap.size();
    int cols = worldMap[0].size();
 
    // Initialize the island count to 0
    int islands = 0;
 
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            if (worldMap[i][j] == 'L') {
                // Found an unvisited land cell,
                // start a new island
                islands++;
                // Explore the entire island using
                // depth-first search
                dfs(worldMap, i, j, rows, cols);
            }
        }
    }
 
    return islands;
}
 
// Driver Code
int main()
{
    vector<vector<char> > worldMap
        = { { 'L', 'W', 'W', 'L' },
            { 'L', 'W', 'W', 'L' },
            { 'L', 'W', 'W', 'L' },
            { 'L', 'W', 'W', 'L' } };
 
    // Calling and printing the answer
    cout << countIslandsOnMap(worldMap) << endl;
 
    return 0;
}


Java




import java.util.ArrayList;
import java.util.List;
 
public class IslandCounter {
 
    // Define possible directions to move
    static List<int[]> directions = List.of(new int[]{-1, 0},
                                            new int[]{1, 0}, new int[]{0, -1}, new int[]{0, 1});
 
    public static void main(String[] args) {
        // Define the world map with 'L' for land and 'W' for water
        char[][] worldMap = {
            {'L', 'W', 'W', 'L'},
            {'L', 'W', 'W', 'L'},
            {'L', 'W', 'W', 'L'},
            {'L', 'W', 'W', 'L'}
        };
 
        int rows = worldMap.length;
        int cols = worldMap[0].length;
 
        // Count the number of islands and print the result
        int islands = countIslandsOnMap(worldMap, rows, cols);
        System.out.println(islands);
    }
 
    // Function to count the number of islands on the map
    public static int countIslandsOnMap(char[][] worldMap, int rows, int cols) {
        int islands = 0;
 
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                if (worldMap[i][j] == 'L') {
                    // Found an unvisited land cell, start a new island
                    islands++;
                    // Explore the entire island using depth-first search
                    dfs(worldMap, i, j, rows, cols);
                }
            }
        }
 
        return islands;
    }
 
    // Depth-First Search to explore and mark connected land cells
    public static void dfs(char[][] worldMap, int row, int col, int rows, int cols) {
        // Mark the current cell as visited
        worldMap[row][col] = 'W';
 
        for (int[] dir : directions) {
            // Cyclically wrap around if needed
            int newRow = (row + dir[0] + rows) % rows;
            int newCol = (col + dir[1] + cols) % cols;
 
            if (worldMap[newRow][newCol] == 'L') {
                // Recursively explore adjacent land cells
                dfs(worldMap, newRow, newCol, rows, cols);
            }
        }
    }
}


Python3




def countIslandsOnMap(worldMap):
    rows = len(worldMap)
    cols = len(worldMap[0])
    islands = 0
    for i in range(rows):
        for j in range(cols):
            if worldMap[i][j] == 'L':
                # Found an unvisited land cell, start a new island
                islands += 1
                # Explore the entire island using depth-first search
                dfs(i, j, rows, cols)
    return islands
 
 
def dfs(row, col, rows, cols):
    # Mark the current cell as visited
    worldMap[row][col] = 'W'
 
    # Explore all adjacent cells, including cyclically wrapping around the map
    # Define possible directions to move
    directions = [(-1, 0), (1, 0), (0, -1), (0, 1)]
    for dr, dc in directions:
        # Cyclically wrap around if needed
        new_row, new_col = (row + dr) % rows, (col + dc) % cols
        if worldMap[new_row][new_col] == 'L':
            # Recursively explore adjacent cells
            dfs(new_row, new_col, rows, cols)
 
 
worldMap = [['L', 'W', 'W', 'L'], ['L', 'W', 'W', 'L'],
            ['L', 'W', 'W', 'L'], ['L', 'W', 'W', 'L']]
 
print(countIslandsOnMap(worldMap))


C#




using System;
using System.Collections.Generic;
 
class Program
{
    // Define possible directions to move
    static List<(int, int)> directions = new List<(int, int)>
    {
        (-1, 0), (1, 0), (0, -1), (0, 1)
    };
 
    static void Dfs(List<List<char>> worldMap, int row, int col, int rows, int cols)
    {
        // Mark the current cell as visited
        worldMap[row][col] = 'W';
 
        // Explore all adjacent cells, including cyclically wrapping around the map
        foreach (var dir in directions)
        {
            // Cyclically wrap around if needed
            int newRow = (row + dir.Item1 + rows) % rows;
            int newCol = (col + dir.Item2 + cols) % cols;
 
            // Check if the adjacent cell is unvisited
            if (worldMap[newRow][newCol] == 'L')
            {
                // Recursively explore adjacent cells
                Dfs(worldMap, newRow, newCol, rows, cols);
            }
        }
    }
 
    static int CountIslandsOnMap(List<List<char>> worldMap)
    {
        int rows = worldMap.Count;
        int cols = worldMap[0].Count;
 
        // Initialize the island count to 0
        int islands = 0;
 
        for (int i = 0; i < rows; i++)
        {
            for (int j = 0; j < cols; j++)
            {
                if (worldMap[i][j] == 'L')
                {
                    // Found an unvisited land cell, start a new island
                    islands++;
 
                    // Explore the entire island using depth-first search
                    Dfs(worldMap, i, j, rows, cols);
                }
            }
        }
 
        return islands;
    }
 
    // Driver Code
    static void Main()
    {
        List<List<char>> worldMap = new List<List<char>>
        {
            new List<char>{'L', 'W', 'W', 'L'},
            new List<char>{'L', 'W', 'W', 'L'},
            new List<char>{'L', 'W', 'W', 'L'},
            new List<char>{'L', 'W', 'W', 'L'}
        };
 
        // Calling and printing the answer
        Console.WriteLine(CountIslandsOnMap(worldMap));
    }
}
 
//This code is contributed by shivamgupta310570


Javascript




function countIslandsOnMap(worldMap) {
    const rows = worldMap.length;
    const cols = worldMap[0].length;
    let islands = 0;
 
    for (let i = 0; i < rows; i++) {
        for (let j = 0; j < cols; j++) {
            if (worldMap[i][j] === 'L') {
                // Found an unvisited land cell, start a new island
                islands += 1;
                // Explore the entire island using depth-first search
                dfs(i, j, rows, cols);
            }
        }
    }
 
    return islands;
}
 
function dfs(row, col, rows, cols) {
    // Mark the current cell as visited
    worldMap[row][col] = 'W';
 
    // Explore all adjacent cells, including cyclically wrapping around the map
    // Define possible directions to move
    let directions = [[-1, 0], [1, 0], [0, -1], [0, 1]];
    for (var i = 0; i <  directions.length; i++) {
         
        let [dr, dc] = directions[i];
         
        // Cyclically wrap around if needed
        const new_row = (row + dr + rows) % rows;
        const new_col = (col + dc + cols) % cols;
 
        if (worldMap[new_row][new_col] === 'L') {
            // Recursively explore adjacent cells
            dfs(new_row, new_col, rows, cols);
        }
    }
}
 
const worldMap = [
    ['L', 'W', 'W', 'L'],
    ['L', 'W', 'W', 'L'],
    ['L', 'W', 'W', 'L'],
    ['L', 'W', 'W', 'L']
];
 
console.log(countIslandsOnMap(worldMap));


Output

1





Time Complexity: O(N * M), where N is the number of rows and M is the number of columns
Auxiliary Space: O(1)



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads