Flood Fill: Region Size
Problem
A grid has r rows and c columns, and each cell holds 0 or 1. A region is a group of cells with the same value, where each cell touches another one of the group on its left, right, top or bottom. Print the number of cells in the region that contains the start cell (row sr, column sc, both counted from 0). Input: the first line is r c sr sc, then r lines with c digits each, written without spaces.
Constraints
- 1 <= r, c <= 50
Examples
Input
3 3 0 0 110 100 001
Output
3
Solutions
The region of a cell is the cell itself plus the regions of its equal neighbours. The visited marks stop the recursion from going back and from counting a cell twice.
/*
* Problem : Size of the region.
* Input : r c sr sc, then the rows.
* Output : The number of cells.
* Approach: Recursive fill
* Time : O(r c)
* Space : O(r c)
* Java : 8 or newer.
*/
import java.util.Scanner;
public class Main {
// Step 2: Visit one cell. A cell outside the grid, a different value, or a cell that was visited before stops the recursion.
static int fill(char[][] grid, boolean[][] seen, int row, int col, char value) {
if (row < 0 || col < 0 || row >= grid.length || col >= grid[0].length || seen[row][col] || grid[row][col] != value) {
return 0;
}
seen[row][col] = true;
// Step 3: This cell counts 1, plus everything that can be reached from its four neighbours.
return 1 + fill(grid, seen, row + 1, col, value) + fill(grid, seen, row - 1, col, value) + fill(grid, seen, row, col + 1, value) + fill(grid, seen, row, col - 1, value);
}
// This method solves the task. It receives the input and returns the answer.
static int solve(String[] lines) {
// Step 1: Read the size, the start cell and the rows.
String[] head = lines[0].split(" ");
int rows = Integer.parseInt(head[0]);
int cols = Integer.parseInt(head[1]);
int startRow = Integer.parseInt(head[2]);
int startCol = Integer.parseInt(head[3]);
char[][] grid = new char[rows][];
for (int i = 0; i < rows; i++) {
grid[i] = lines[i + 1].toCharArray();
}
return fill(grid, new boolean[rows][cols], startRow, startCol, grid[startRow][startCol]);
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
java.util.List<String> all = new java.util.ArrayList<>();
while (scanner.hasNextLine()) {
String line = scanner.nextLine().trim();
if (!line.isEmpty()) {
all.add(line);
}
}
String[] lines = all.toArray(new String[0]);
System.out.println(solve(lines));
}
}
Hints (2)
- What stops the recursion?
- Why mark a cell before visiting its neighbours?