Number of Islands medium
Problem Statement
Given an m x n
2D binary grid grid
which represents a map of '1's (land) and '0's (water), return the number of islands.
An island is surrounded by water and is formed by connecting adjacent lands horizontally or vertically. You may assume all four edges of the grid are all surrounded by water.
Example 1:
Input: grid = [ ["1","1","1","1","0"], ["1","1","0","1","0"], ["1","1","0","0","0"], ["0","0","0","0","0"] ] Output: 1
Example 2:
Input: grid = [ ["1","1","0","0","0"], ["1","1","0","0","0"], ["0","0","1","0","0"], ["0","0","0","1","1"] ] Output: 3
Steps and Explanation
The solution uses Depth-First Search (DFS) to count the number of islands. The algorithm iterates through each cell in the grid. If a cell contains '1' (land) and hasn't been visited yet, it means a new island has been found. A DFS function is then called to explore all connected land cells, marking them as visited. The count of islands is incremented for each new island found.
-
Initialization: Create a
visited
array of the same dimensions as the inputgrid
to keep track of visited cells. Initialize it with allfalse
values. Initialize anumIslands
counter to 0. -
Iteration: Iterate through each cell of the
grid
. -
Island Detection: If a cell contains '1' (land) and hasn't been visited (
visited[i][j] == false
), it represents a new island. IncrementnumIslands
. -
Depth-First Search (DFS): Call a recursive DFS function to explore all connected land cells. The DFS function marks the current cell as visited and recursively calls itself for its adjacent unvisited land cells (up, down, left, right).
-
Return: After iterating through the entire grid, return
numIslands
.
Code (Java)
class Solution {
public int numIslands(char[][] grid) {
int numRows = grid.length;
if (numRows == 0) return 0; //Handle empty grid
int numCols = grid[0].length;
boolean[][] visited = new boolean[numRows][numCols];
int numIslands = 0;
for (int i = 0; i < numRows; i++) {
for (int j = 0; j < numCols; j++) {
if (grid[i][j] == '1' && !visited[i][j]) {
numIslands++;
dfs(grid, visited, i, j);
}
}
}
return numIslands;
}
private void dfs(char[][] grid, boolean[][] visited, int row, int col) {
int numRows = grid.length;
int numCols = grid[0].length;
if (row < 0 || row >= numRows || col < 0 || col >= numCols || grid[row][col] == '0' || visited[row][col]) {
return;
}
visited[row][col] = true;
dfs(grid, visited, row + 1, col);
dfs(grid, visited, row - 1, col);
dfs(grid, visited, row, col + 1);
dfs(grid, visited, row, col - 1);
}
}
Complexity Analysis
-
Time Complexity: O(M * N), where M and N are the number of rows and columns in the grid respectively. In the worst case, we visit each cell once.
-
Space Complexity: O(M * N) in the worst case. This is due to the
visited
array, which stores the visited status of each cell. The recursive call stack of DFS can also consume space, but it's bounded by the maximum depth of the recursion which is at most M * N in the worst-case scenario of a single large island. Therefore, the space complexity is dominated by the visited array.