The "Number of Enclaves" problem asks you to count the number of land cells in a 2D grid that cannot reach the boundary of the grid by moving up, down, left, or right.
The grid is represented as a 2D array grid
where grid[i][j] == 1
means the cell is land and grid[i][j] == 0
means the cell is water.
A land cell is considered an enclave if it cannot walk off the boundary of the grid in any number of moves. You can only move to adjacent land cells (no diagonals). The task is to return the total number of such enclave land cells.
At first glance, one might think about counting all the land cells and then trying to check, for each, if a path exists to the boundary. However, checking for each cell individually would be very inefficient.
Instead, notice that the only land cells that cannot reach the boundary are those that are fully surrounded by water or other land cells not connected to the edge. So, if we can remove all land cells that are connected to the boundary, the remaining ones are enclaves.
This leads to a more efficient approach: "flood fill" (BFS or DFS) from the boundary land cells, marking all land they can reach. Then, count the land cells that remain unvisited.
The algorithm can be broken down into the following steps:
1
), start a flood fill (DFS or BFS).
0
or using a visited array).
1
). These are enclaves.
We use flood fill because it efficiently marks all reachable land from the boundary in O(N) time, and we avoid extra space by modifying the grid in place.
Consider this grid:
grid = [ [0,0,0,0], [1,0,1,0], [0,1,1,0], [0,0,0,0] ]
The answer is 4.
The key insight is to realize that only land cells not connected to the boundary are enclaves. By removing all land reachable from the boundary via a flood fill, we efficiently isolate and count the enclaves. This approach is both simple and optimal for the problem constraints.
class Solution:
def numEnclaves(self, grid: List[List[int]]) -> int:
m, n = len(grid), len(grid[0])
def dfs(x, y):
if x < 0 or x >= m or y < 0 or y >= n or grid[x][y] == 0:
return
grid[x][y] = 0
for dx, dy in [(-1,0),(1,0),(0,-1),(0,1)]:
dfs(x+dx, y+dy)
for i in range(m):
for j in [0, n-1]:
if grid[i][j] == 1:
dfs(i, j)
for j in range(n):
for i in [0, m-1]:
if grid[i][j] == 1:
dfs(i, j)
return sum(grid[i][j] == 1 for i in range(m) for j in range(n))
class Solution {
public:
void dfs(vector<vector<int>>& grid, int x, int y, int m, int n) {
if (x < 0 || x >= m || y < 0 || y >= n || grid[x][y] == 0) return;
grid[x][y] = 0;
int dirs[4][2] = {{-1,0},{1,0},{0,-1},{0,1}};
for (auto& d : dirs) {
dfs(grid, x + d[0], y + d[1], m, n);
}
}
int numEnclaves(vector<vector<int>>& grid) {
int m = grid.size(), n = grid[0].size();
for (int i = 0; i < m; ++i) {
if (grid[i][0] == 1) dfs(grid, i, 0, m, n);
if (grid[i][n-1] == 1) dfs(grid, i, n-1, m, n);
}
for (int j = 0; j < n; ++j) {
if (grid[0][j] == 1) dfs(grid, 0, j, m, n);
if (grid[m-1][j] == 1) dfs(grid, m-1, j, m, n);
}
int count = 0;
for (int i = 0; i < m; ++i)
for (int j = 0; j < n; ++j)
if (grid[i][j] == 1) count++;
return count;
}
};
class Solution {
int m, n;
public int numEnclaves(int[][] grid) {
m = grid.length;
n = grid[0].length;
for (int i = 0; i < m; ++i) {
if (grid[i][0] == 1) dfs(grid, i, 0);
if (grid[i][n-1] == 1) dfs(grid, i, n-1);
}
for (int j = 0; j < n; ++j) {
if (grid[0][j] == 1) dfs(grid, 0, j);
if (grid[m-1][j] == 1) dfs(grid, m-1, j);
}
int count = 0;
for (int i = 0; i < m; ++i)
for (int j = 0; j < n; ++j)
if (grid[i][j] == 1) count++;
return count;
}
void dfs(int[][] grid, int x, int y) {
if (x < 0 || x >= m || y < 0 || y >= n || grid[x][y] == 0) return;
grid[x][y] = 0;
int[][] dirs = {{-1,0},{1,0},{0,-1},{0,1}};
for (int[] d : dirs)
dfs(grid, x + d[0], y + d[1]);
}
}
var numEnclaves = function(grid) {
const m = grid.length, n = grid[0].length;
function dfs(x, y) {
if (x < 0 || x >= m || y < 0 || y >= n || grid[x][y] === 0) return;
grid[x][y] = 0;
[[-1,0],[1,0],[0,-1],[0,1]].forEach(([dx, dy]) => dfs(x+dx, y+dy));
}
for (let i = 0; i < m; ++i) {
if (grid[i][0] === 1) dfs(i, 0);
if (grid[i][n-1] === 1) dfs(i, n-1);
}
for (let j = 0; j < n; ++j) {
if (grid[0][j] === 1) dfs(0, j);
if (grid[m-1][j] === 1) dfs(m-1, j);
}
let count = 0;
for (let i = 0; i < m; ++i)
for (let j = 0; j < n; ++j)
if (grid[i][j] === 1) count++;
return count;
};