[LeetCode] 1020. Number of Enclaves

You are given an m x n binary matrix grid, where 0 represents a sea cell and 1 represents a land cell.

A move consists of walking from one land cell to another adjacent (4-directionally) land cell or walking off the boundary of the grid.

Return the number of land cells in grid for which we cannot walk off the boundary of the grid in any number of moves.

Example 1:

Input: grid = [[0,0,0,0],[1,0,1,0],[0,1,1,0],[0,0,0,0]]
Output: 3
Explanation: There are three 1s that are enclosed by 0s, and one 1 that is not enclosed because its on the boundary.

Example 2:

Input: grid = [[0,1,1,0],[0,0,1,0],[0,0,1,0],[0,0,0,0]]
Output: 0
Explanation: All 1s are either on the boundary or can reach the boundary.

Constraints:
m == grid.length
n == grid[i].length
1 <= m, n <= 500
grid[i][j] is either 0 or 1.

飞地的数量。

给你一个大小为 m x n 的二进制矩阵 grid ,其中 0 表示一个海洋单元格、1 表示一个陆地单元格。

一次 移动 是指从一个陆地单元格走到另一个相邻(上、下、左、右)的陆地单元格或跨过 grid 的边界。

返回网格中 无法 在任意次数的移动中离开网格边界的陆地单元格的数量。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/number-of-enclaves
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路

题意不难理解,就是变相的 flood fill 类型的题目。这里我给出 BFS 和 DFS 两种解法,时间复杂度均为O(mn),空间复杂度均为O(n)。如果代码看不懂,请先移步 200 题。无论是哪种做法,都需要遍历 matrix 两遍。第一遍先找 matrix 边界上的 1,然后 traverse,把遇到的所有的 1 改成 0。再一次遍历 matrix,如果 matrix 中还有 1,就说明这些 1 是飞地,无法离开 matrix 的。注意这道题其实让你求的是飞地的面积而不是飞地的数量,所以要累加所有遇到的 1。

复杂度

时间O(mn)
空间O(n)

BFS代码

Java实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
class Solution {
int m;
int n;
int[] dx = {-1, 1, 0, 0};
int[] dy = {0, 0, -1, 1};

public int numEnclaves(int[][] grid) {
m = grid.length;
n = grid[0].length;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
// 处理边界上的1
if ((i == 0 || i == m - 1 || j == 0 || j == n - 1) && grid[i][j] == 1) {
bfs(grid, i, 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;
}

private void bfs(int[][] grid, int i, int j) {
Queue<int[]> queue = new LinkedList<>();
queue.offer(new int[] { i, j });
while (!queue.isEmpty()) {
int[] cur = queue.poll();
int x = cur[0];
int y = cur[1];
grid[x][y] = 0;
for (int k = 0; k < 4; k++) {
int newX = x + dx[k];
int newY = y + dy[k];
if (newX >= 0 && newX < m && newY >= 0 && newY < n && grid[newX][newY] == 1) {
queue.offer(new int[] { newX, newY });
}
}
}
}
}

DFS代码

Java实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
class Solution {
int m;
int n;

public int numEnclaves(int[][] grid) {
m = grid.length;
n = grid[0].length;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
// 处理边界上的 1
if ((i == 0 || j == 0 || i == m - 1 || j == n - 1) && grid[i][j] == 1) {
dfs(grid, i, j);
}
}
}

// 处理不能触及边界的 1
int res = 0;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (grid[i][j] == 1) {
res++;
}
}
}
return res;
}

private void dfs(int[][] grid, int i, int j) {
if (i < 0 || j < 0 || i >= m || j >= n || grid[i][j] == 0) {
return;
}
grid[i][j] = 0;
dfs(grid, i - 1, j);
dfs(grid, i + 1, j);
dfs(grid, i, j - 1);
dfs(grid, i, j + 1);
}
}

[LeetCode] 1020. Number of Enclaves
https://shurui91.github.io/posts/493219565.html
Author
Aaron Liu
Posted on
December 22, 2020
Licensed under