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
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
Two islands in the matrix
Input: grid[][] = [['W,' 'W'], ['W', 'W']] Output: 0 All elements are 0, hence no islands.
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
[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>usingnamespacestd;// A function to check if a given// cell (r, c) can be included in DFSboolisSafe(vector<vector<char>>&grid,intr,intc,vector<vector<bool>>&visited){introw=grid.size();intcol=grid[0].size();// r is in range, c is in range, value // is 'L' (land) and not yet visitedreturn(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 verticesvoiddfs(vector<vector<char>>&grid,intr,intc,vector<vector<bool>>&visited){// These arrays are used to get// r and c numbers of 8// neighbours of a given cellvector<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 visitedvisited[r][c]=true;// Recur for all connected neighboursfor(intk=0;k<8;++k){intnewR=r+rNbr[k];intnewC=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 matrixintcountIslands(vector<vector<char>>&grid){introw=grid.size();intcol=grid[0].size();// Make a bool array to mark visited cells.// Initially all cells are unvisitedvector<vector<bool>>visited(row,vector<bool>(col,false));// Initialize count as 0 and traverse through// all cells of the given matrixintcount=0;for(intr=0;r<row;++r){for(intc=0;c<col;++c){// If a cell with value 'L' (land) is not visited yet,// then a new island is foundif(grid[r][c]=='L'&&!visited[r][c]){// Visit all cells in this island.dfs(grid,r,c,visited);// Increment the island count++count;}}}returncount;}intmain(){// Updated grid with 'L' for land and 'W' for watervector<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;return0;}
Java
importjava.util.*;classGfG{// A function to check if a given// cell (r, c) can be included in DFSstaticbooleanisSafe(char[][]grid,intr,intc,boolean[][]visited){introw=grid.length;intcol=grid[0].length;// r is in range, c is in range, value // is 'L' (land) and not yet visitedreturn(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 verticesstaticvoiddfs(char[][]grid,intr,intc,boolean[][]visited){// These arrays are used to get// r and c numbers of 8// neighbours of a given cellint[]rNbr={-1,-1,-1,0,0,1,1,1};int[]cNbr={-1,0,1,-1,1,-1,0,1};// Mark this cell as visitedvisited[r][c]=true;// Recur for all connected neighboursfor(intk=0;k<8;++k){intnewR=r+rNbr[k];intnewC=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 matrixstaticintcountIslands(char[][]grid){introw=grid.length;intcol=grid[0].length;// Make a bool array to mark visited cells.// Initially all cells are unvisitedboolean[][]visited=newboolean[row][col];// Initialize count as 0 and traverse through// all cells of the given matrixintcount=0;for(intr=0;r<row;++r){for(intc=0;c<col;++c){// If a cell with value 'L' (land) is not visited yet,// then a new island is foundif(grid[r][c]=='L'&&!visited[r][c]){// Visit all cells in this island.dfs(grid,r,c,visited);// Increment the island count++count;}}}returncount;}publicstaticvoidmain(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
defisSafe(grid,r,c,visited):row=len(grid)col=len(grid[0])return(0<=r<row)and(0<=c<col)and(grid[r][c]=='L'andnotvisited[r][c])defdfs(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 visitedvisited[r][c]=True# Recur for all connected neighboursforkinrange(8):newR,newC=r+rNbr[k],c+cNbr[k]ifisSafe(grid,newR,newC,visited):dfs(grid,newR,newC,visited)defcountIslands(grid):row=len(grid)col=len(grid[0])visited=[[Falsefor_inrange(col)]for_inrange(row)]count=0forrinrange(row):forcinrange(col):# If a cell with value 'L' (land) is not visited yet,# then a new island is foundifgrid[r][c]=='L'andnotvisited[r][c]:# Visit all cells in this island.dfs(grid,r,c,visited)# increment the island countcount+=1returncountif__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 matrixusingSystem;classGfG{// A function to check if a given// cell (r, c) can be included in DFSstaticboolisSafe(char[,]grid,intr,intc,bool[,]visited){introw=grid.GetLength(0);intcol=grid.GetLength(1);// r is in range, c is in range, value // is 'L' and not yet visitedreturn(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 verticesstaticvoiddfs(char[,]grid,intr,intc,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(intk=0;k<8;k++){intnewR=r+rNbr[k];intnewC=c+cNbr[k];if(isSafe(grid,newR,newC,visited)){dfs(grid,newR,newC,visited);}}}staticintcountIslands(char[,]grid){introw=grid.GetLength(0);intcol=grid.GetLength(1);bool[,]visited=newbool[row,col];intcount=0;for(intr=0;r<row;r++){for(intc=0;c<col;c++){if(grid[r,c]=='L'&&!visited[r,c]){dfs(grid,r,c,visited);count++;}}}returncount;}staticvoidMain(){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 matrixfunctionisSafe(grid,r,c,visited){constrow=grid.length;constcol=grid[0].length;// r is in range, c is in range, value // is 'L' and not yet visitedreturn(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 verticesfunctiondfs(grid,r,c,visited){constrNbr=[-1,-1,-1,0,0,1,1,1];constcNbr=[-1,0,1,-1,1,-1,0,1];visited[r][c]=true;// Recur for all connected neighboursfor(letk=0;k<8;k++){constnewR=r+rNbr[k];constnewC=c+cNbr[k];if(isSafe(grid,newR,newC,visited)){dfs(grid,newR,newC,visited);}}}// Function to count the number of islandsfunctioncountIslands(grid){constrow=grid.length;constcol=grid[0].length;// Create a visited matrixconstvisited=Array.from({length:row},()=>Array(col).fill(false));letcount=0;// Traverse all cells in the gridfor(letr=0;r<row;r++){for(letc=0;c<col;c++){if(grid[r][c]==='L'&&!visited[r][c]){// If it's land and not visited, start DFSdfs(grid,r,c,visited);count++;// Increment island count}}}returncount;}// Example usage:constgrid=[['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>usingnamespacestd;voiddfs(vector<vector<char>>&grid,intr,intc){introw=grid.size();intcol=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 directionsvector<int>rNbr={1,-1,0,0,1,-1,1,-1};vector<int>cNbr={0,0,1,-1,1,-1,-1,1};for(inti=0;i<8;++i){intnewR=r+rNbr[i];intnewC=c+cNbr[i];dfs(grid,newR,newC);}}// Function to count the number of islandsintcountIslands(vector<vector<char>>&grid){introw=grid.size();intcol=grid[0].size();intcount=0;// Traverse the entire matrixfor(intr=0;r<row;r++){for(intc=0;c<col;c++){// If a cell with value 'L' (land) is foundif(grid[r][c]=='L'){// Increment the island countcount++;// Start DFS from the current celldfs(grid,r,c);}}}returncount;}intmain(){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;return0;}
Java
classGfG{// A utility function to do DFS for a// 2D matrix. It only considers// the 8 neighbors as adjacent verticesstaticvoiddfs(char[][]grid,intr,intc){// These arrays are used to get// r and c numbers of 8// neighbours of a given cellintrow=grid.length;intcol=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 neighboursfor(intk=0;k<8;++k){intnewR=r+rNbr[k];intnewC=c+cNbr[k];dfs(grid,newR,newC);}}// The main function that returns// count of islands in a given matrixstaticintcountIslands(char[][]grid){introw=grid.length;intcol=grid[0].length;// Initialize count as 0 and traverse through// all cells of the given matrixintcount=0;for(intr=0;r<row;++r){for(intc=0;c<col;++c){// If a cell with value 'L' (land) is found,// then a new island is foundif(grid[r][c]=='L'){// Visit all cells in this island.dfs(grid,r,c);// Increment the island count++count;}}}returncount;}publicstaticvoidmain(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 DFSdefisSafe(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)andgrid[r][c]=='L'# A utility function to do DFS for a# 2D matrix. It only considers# the 8 neighbors as adjacent verticesdefdfs(grid,r,c):# These arrays are used to get# r and c numbers of 8# neighbours of a given cellrNbr=[-1,-1,-1,0,0,1,1,1]cNbr=[-1,0,1,-1,1,-1,0,1]# Mark this cell as visitedgrid[r][c]='W'# Recur for all connected neighboursforkinrange(8):newR=r+rNbr[k]newC=c+cNbr[k]ifisSafe(grid,newR,newC):dfs(grid,newR,newC)# The main function that returns# count of islands in a given matrixdefcountIslands(grid):row=len(grid)col=len(grid[0])count=0forrinrange(row):forcinrange(col):ifgrid[r][c]=='L':dfs(grid,r,c)count+=1returncount# Main executionif__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#
usingSystem;classGfG{// A utility function to check boundaries and if the cell is landstaticboolisSafe(char[,]grid,intr,intc,introw,intcol){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 verticesstaticvoiddfs(char[,]grid,intr,intc,introw,intcol){// Check base conditionif(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 cellint[]rNbr={-1,-1,-1,0,0,1,1,1};int[]cNbr={-1,0,1,-1,1,-1,0,1};// Mark this cell as visitedgrid[r,c]='W';// Recur for all connected neighborsfor(intk=0;k<8;++k){intnewR=r+rNbr[k];intnewC=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 matrixstaticintcountIslands(char[,]grid){introw=grid.GetLength(0);intcol=grid.GetLength(1);// Initialize count as 0 and traverse through// all cells of the given matrixintcount=0;for(intr=0;r<row;++r){for(intc=0;c<col;++c){// If a cell with value 'L' (land) is found,// then a new island is foundif(grid[r,c]=='L'){// Visit all cells in this island.dfs(grid,r,c,row,col);// Increment the island count++count;}}}returncount;}staticvoidMain(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
functionisSafe(grid,r,c){letrow=grid.length;letcol=grid[0].length;// r is in range, c is in range, value // is 'L' (land) and not yet visitedreturnr>=0&&r<row&&c>=0&&c<col&&grid[r][c]==='L';}functiondfs(grid,r,c){letrNbr=[-1,-1,-1,0,0,1,1,1];letcNbr=[-1,0,1,-1,1,-1,0,1];// Mark this cell as visitedgrid[r][c]='W';// Recur for all connected neighborsfor(letk=0;k<8;++k){letnewR=r+rNbr[k];letnewC=c+cNbr[k];if(isSafe(grid,newR,newC)){dfs(grid,newR,newC);}}}// The main function that returns// count of islands in a given matrixfunctioncountIslands(grid){letrow=grid.length;letcol=grid[0].length;letcount=0;for(letr=0;r<row;++r){for(letc=0;c<col;++c){// If a cell with value 'L' (land) is found,// then a new island is foundif(grid[r][c]==='L'){// Visit all cells in this island.dfs(grid,r,c);// increment the island count++count;}}}returncount;}// Test case with grid containing 'L' for land and 'W' for waterletgrid=[['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.
[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.
We use cookies to ensure you have the best browsing experience on our website. By using our site, you
acknowledge that you have read and understood our
Cookie Policy &
Privacy Policy
Improvement
Suggest Changes
Help us improve. Share your suggestions to enhance the article. Contribute your expertise and make a difference in the GeeksforGeeks portal.
Create Improvement
Enhance the article with your expertise. Contribute to the GeeksforGeeks community and help create better learning resources for all.