Number of Islands
Problem
A grid has 1 for land and 0 for water. An island is a group of land cells connected up, down, left or right. Print the number of islands.
Constraints
- 1 <= r, c <= 100
Examples
Input
4 5 1 1 0 0 0 1 1 0 0 0 0 0 1 0 0 0 0 0 1 1
Output
3
Solutions
We scan the grid. A land cell that is not visited yet starts a new island, and a flood fill marks all its cells. We use an explicit stack instead of recursion, so a big island can not overflow the call stack.
/*
* Problem : Process a grid.
* Input : r and c, then r rows of c numbers (0 or 1).
* Output : The number of islands.
* Approach: Flood fill each island once.
* Time : O(r * c)
* Space : O(r * c)
* Java : 8 or newer.
*/
import java.util.Scanner;
public class Main {
// This method solves the task. It receives the input and returns the answer.
static int solve(int[][] m) {
int rows = m.length;
int cols = m[0].length;
boolean[][] visited = new boolean[rows][cols];
int islands = 0;
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
// Step 1: A land cell that was not visited belongs to a new island.
if (m[i][j] == 1 && !visited[i][j]) {
islands++;
// Step 2: Visit the whole island with a stack (depth-first search) and mark every cell.
java.util.ArrayDeque<int[]> stack = new java.util.ArrayDeque<>();
stack.push(new int[] {i, j});
visited[i][j] = true;
while (!stack.isEmpty()) {
int[] cell = stack.pop();
int[][] neighbours = {{cell[0] + 1, cell[1]}, {cell[0] - 1, cell[1]}, {cell[0], cell[1] + 1}, {cell[0], cell[1] - 1}};
for (int[] next : neighbours) {
if (next[0] >= 0 && next[0] < rows && next[1] >= 0 && next[1] < cols
&& m[next[0]][next[1]] == 1 && !visited[next[0]][next[1]]) {
visited[next[0]][next[1]] = true;
stack.push(next);
}
}
}
}
}
}
// Step 3: The number of starts is the number of islands.
return islands;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int rows = scanner.nextInt();
int cols = scanner.nextInt();
int[][] m = new int[rows][cols];
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
m[i][j] = scanner.nextInt();
}
}
System.out.println(solve(m));
}
}
Hints (2)
- Why do we mark cells as visited?
- Why use a stack instead of recursion?