class Solution:
def closedIsland(self, grid: List[List[int]]) -> int:
rows, cols = len(grid), len(grid[0])
def dfs(r, c):
if r < 0 or c < 0 or r >= rows or c >= cols:
return False
if grid[r][c] == 1:
return True
grid[r][c] = 1 # mark as visited
up = dfs(r - 1, c)
down = dfs(r + 1, c)
left = dfs(r, c - 1)
right = dfs(r, c + 1)
return up and down and left and right
count = 0
for r in range(rows):
for c in range(cols):
if grid[r][c] == 0:
if dfs(r, c):
count += 1
return count
class Solution {
public:
int closedIsland(vector<vector<int>>& grid) {
int rows = grid.size(), cols = grid[0].size();
function<bool(int, int)> dfs = [&](int r, int c) {
if (r < 0 || c < 0 || r >= rows || c >= cols) return false;
if (grid[r][c] == 1) return true;
grid[r][c] = 1;
bool up = dfs(r - 1, c);
bool down = dfs(r + 1, c);
bool left = dfs(r, c - 1);
bool right = dfs(r, c + 1);
return up && down && left && right;
};
int count = 0;
for (int r = 0; r < rows; ++r) {
for (int c = 0; c < cols; ++c) {
if (grid[r][c] == 0) {
if (dfs(r, c)) ++count;
}
}
}
return count;
}
};
class Solution {
public int closedIsland(int[][] grid) {
int rows = grid.length, cols = grid[0].length;
int count = 0;
for (int r = 0; r < rows; r++) {
for (int c = 0; c < cols; c++) {
if (grid[r][c] == 0) {
if (dfs(grid, r, c, rows, cols)) {
count++;
}
}
}
}
return count;
}
private boolean dfs(int[][] grid, int r, int c, int rows, int cols) {
if (r < 0 || c < 0 || r >= rows || c >= cols) return false;
if (grid[r][c] == 1) return true;
grid[r][c] = 1;
boolean up = dfs(grid, r - 1, c, rows, cols);
boolean down = dfs(grid, r + 1, c, rows, cols);
boolean left = dfs(grid, r, c - 1, rows, cols);
boolean right = dfs(grid, r, c + 1, rows, cols);
return up && down && left && right;
}
}
var closedIsland = function(grid) {
const rows = grid.length, cols = grid[0].length;
function dfs(r, c) {
if (r < 0 || c < 0 || r >= rows || c >= cols) return false;
if (grid[r][c] === 1) return true;
grid[r][c] = 1;
let up = dfs(r - 1, c);
let down = dfs(r + 1, c);
let left = dfs(r, c - 1);
let right = dfs(r, c + 1);
return up && down && left && right;
}
let count = 0;
for (let r = 0; r < rows; r++) {
for (let c = 0; c < cols; c++) {
if (grid[r][c] === 0) {
if (dfs(r, c)) count++;
}
}
}
return count;
};
You are given a 2D grid of integers where 0
represents land and 1
represents water. An island is a group of connected 0
s (land) connected 4-directionally (up, down, left, right). A closed island is an island that is completely surrounded by water (i.e., it does not touch the grid's border at any point).
The task is to count the number of closed islands in the grid. You must ensure that each land cell is used in at most one island, and you cannot reuse elements between islands.
grid
- a 2D list of integers (0s and 1s)At first glance, the problem seems similar to counting islands in a grid, a classic DFS/BFS problem. However, the twist is that only islands which do not touch the grid border are considered "closed".
A brute-force approach would be to search for every group of connected land (0s) and, for each group, check if any part of it touches the border. If it does, it's not closed. Otherwise, it's a closed island.
To optimize, we can merge the detection and marking steps: as we traverse each island with DFS or BFS, we can simultaneously check if we ever reach the border. If so, we know immediately that this island isn't closed, saving us from extra checks.
The key insight is that an island is closed if, during traversal, none of its land cells are on the border. We can use recursion to propagate this status up as we visit each cell.
0
), start a DFS (or BFS) traversal from there.
1
). This prevents revisiting the same cell and ensures each land cell is only part of one island.
This approach ensures we only visit each cell once and immediately know if an island is closed or not as we traverse it.
Consider the following grid:
1 1 1 1 1 1 1 0 1 0 0 0 0 1 1 0 1 0 1 0 1 1 1 0 1 0 0 0 0 1 0 1 1 1 1 1 1 1 1 0
0
we find is at (1,1).0
s as visited.0
is at (3,6). We start a DFS and see that it connects to the border at (4,7), so this is not a closed island.The optimized approach is efficient and suitable for large grids.
The "Number of Closed Islands" problem is a variation of the classic island-counting task, with the added challenge of only counting islands fully surrounded by water. By using DFS or BFS to traverse each island and marking visited cells, we efficiently identify closed islands by checking border contact during traversal. The solution is elegant because it combines marking and checking in a single pass, ensuring optimal performance and clarity.