Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit de11f14

Browse files
Merge pull request SharingSource#357 from SharingSource/ac_oier
✨feat: Add 1020
2 parents 7de5697 + 59c1147 commit de11f14

File tree

3 files changed

+128
-0
lines changed

3 files changed

+128
-0
lines changed

‎Index/图论 DFS.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
| [778. 水位上升的泳池中游泳](https://leetcode-cn.com/problems/swim-in-rising-water/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/swim-in-rising-water/solution/gong-shui-san-xie-yi-ti-shuang-jie-krusk-7c6o/) | 困难 | 🤩🤩🤩 |
55
| [797. 所有可能的路径](https://leetcode-cn.com/problems/all-paths-from-source-to-target/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/all-paths-from-source-to-target/solution/gong-shui-san-xie-yun-yong-dfs-bao-sou-s-xlz9/) | 中等 | 🤩🤩🤩🤩 |
66
| [863. 二叉树中所有距离为 K 的结点](https://leetcode-cn.com/problems/all-nodes-distance-k-in-binary-tree/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/all-nodes-distance-k-in-binary-tree/solution/gong-shui-san-xie-yi-ti-shuang-jie-jian-x6hak/) | 中等 | 🤩🤩🤩🤩 |
7+
| [1020. 飞地的数量](https://leetcode-cn.com/problems/number-of-enclaves/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/number-of-enclaves/solution/gong-shui-san-xie-bing-cha-ji-dfs-yun-yo-oyh1/) | 中等 | 🤩🤩🤩 |
78
| [1034. 边界着色](https://leetcode-cn.com/problems/coloring-a-border/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/coloring-a-border/solution/gong-shui-san-xie-tu-lun-sou-suo-zhuan-t-snvw/) | 中等 | 🤩🤩🤩🤩 |
89
| [1723. 完成所有工作的最短时间](https://leetcode-cn.com/problems/find-minimum-time-to-finish-all-jobs/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/find-minimum-time-to-finish-all-jobs/solution/gong-shui-san-xie-yi-ti-shuang-jie-jian-4epdd/) | 困难 | 🤩🤩🤩 |
910
| [1766. 互质树](https://leetcode-cn.com/problems/tree-of-coprimes/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/tree-of-coprimes/solution/bu-tai-yi-yang-de-dfs-ji-lu-suo-you-zui-d3xeu/) | 困难 | 🤩🤩🤩🤩 |

‎Index/并查集.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@
22
| ------------------------------------------------------------ | ------------------------------------------------------------ | ---- | -------- |
33
| [765. 情侣牵手](https://leetcode-cn.com/problems/couples-holding-hands/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/couples-holding-hands/solution/liang-chong-100-de-jie-fa-bing-cha-ji-ta-26a6/) | 困难 | 🤩🤩🤩 |
44
| [778. 水位上升的泳池中游泳](https://leetcode-cn.com/problems/swim-in-rising-water/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/swim-in-rising-water/solution/gong-shui-san-xie-yi-ti-shuang-jie-krusk-7c6o/) | 困难 | 🤩🤩🤩 |
5+
| [1020. 飞地的数量](https://leetcode-cn.com/problems/number-of-enclaves/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/number-of-enclaves/solution/gong-shui-san-xie-bing-cha-ji-dfs-yun-yo-oyh1/) | 中等 | 🤩🤩🤩 |
56
| [1631. 最小体力消耗路径](https://leetcode-cn.com/problems/path-with-minimum-effort/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/path-with-minimum-effort/solution/fan-zheng-fa-zheng-ming-si-lu-de-he-fa-x-ohby/) | 中等 | 🤩🤩🤩 |
67

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
### 题目描述
2+
3+
这是 LeetCode 上的 **[1020. 飞地的数量](https://assets.leetcode.com/uploads/2021/02/18/enclaves1.jpg)** ,难度为 **中等**
4+
5+
Tag : 「DFS」、「并查集」
6+
7+
8+
9+
给你一个大小为 $m x n$ 的二进制矩阵 $grid$ ,其中 0ドル$ 表示一个海洋单元格、1ドル$ 表示一个陆地单元格。
10+
11+
一次 移动 是指从一个陆地单元格走到另一个相邻(上、下、左、右)的陆地单元格或跨过 $grid$ 的边界。
12+
13+
返回网格中 无法 在任意次数的移动中离开网格边界的陆地单元格的数量。
14+
15+
示例 1:
16+
![](https://assets.leetcode.com/uploads/2021/02/18/enclaves1.jpg)
17+
```
18+
输入:grid = [[0,0,0,0],[1,0,1,0],[0,1,1,0],[0,0,0,0]]
19+
20+
输出:3
21+
22+
解释:有三个 1 被 0 包围。一个 1 没有被包围,因为它在边界上。
23+
```
24+
示例 2:
25+
![](https://assets.leetcode.com/uploads/2021/02/18/enclaves2.jpg)
26+
```
27+
输入:grid = [[0,1,1,0],[0,0,1,0],[0,0,1,0],[0,0,0,0]]
28+
29+
输出:0
30+
31+
解释:所有 1 都在边界上或可以到达边界。
32+
```
33+
34+
提示:
35+
* $m == grid.length$
36+
* $n == grid[i].length$
37+
* 1ドル <= m, n <= 500$
38+
* $grid[i][j]$ 的值为 0ドル$ 或 1ドル$
39+
40+
---
41+
42+
### 并查集 + DFS
43+
44+
根据题目定义,我们知道需要统计所有不和「边缘陆地」相连通的「普通陆地」数量。
45+
46+
我们可以用「并查集」来维护连通块,使用 `DFS` 对所有「边缘陆地连通块」进行标记(设定编号为 0ドル$ 的超级源点,对于所有的「边缘陆地连通块」,将其与超级源点联通)。
47+
48+
具体的,我们按照如下流程进行处理:
49+
50+
* 初始化并查集:起始让每个单元格独立作为一个连通块;
51+
* 使用 `DFS` 标记所有「边缘陆地连通块」:从位于边缘的「边缘陆地」进行出发,将其所在连通块与超级源点 0ドル$ 进行联通标记(同时为了确保复杂度,我们在进行 `DFS` 前需要先检查当前陆地与超级源点的联通关系,如果已联通,说明当前陆地棣属于之前的某个连通块,已被整体标记过,进行跳过即可);
52+
* 统计答案:遍历整个棋盘,统计所有不与超级源点 0ドル$ 联通的陆地数量。
53+
54+
> 一些细节:由于我们人为规定了超级源点编号为 0ドル,ドル同时棋盘下标从 0ドル$ 开始,因此对某个点 $(x, y)$ 的编号,我们需要增加一个偏移量,例如 $idx = x * n + y + 1$。
55+
56+
代码:
57+
```Java
58+
class Solution {
59+
int N = 550;
60+
int[] p = new int[N * N];
61+
int m, n;
62+
int[][] g;
63+
int find(int x) {
64+
if (p[x] != x) p[x] = find(p[x]);
65+
return p[x];
66+
}
67+
boolean query(int a, int b) {
68+
return find(a) == find(b);
69+
}
70+
void union(int a, int b) {
71+
p[find(a)] = find(b);
72+
}
73+
public int numEnclaves(int[][] grid) {
74+
g = grid;
75+
m = g.length; n = g[0].length;
76+
for (int i = 0; i < m; i++) {
77+
for (int j = 0; j < n; j++) {
78+
p[getIdx(i, j)] = getIdx(i, j);
79+
}
80+
}
81+
for (int i = 0; i < m; i++) {
82+
for (int j = 0; j < n; j++) {
83+
if (i == 0 || j == 0 || i == m - 1 || j == n - 1) {
84+
if (g[i][j] != 1 || query(getIdx(i, j), 0)) continue;
85+
dfs(i, j);
86+
}
87+
}
88+
}
89+
int ans = 0;
90+
for (int i = 0; i < m; i++) {
91+
for (int j = 0; j < n; j++) {
92+
if (g[i][j] == 1 && !query(getIdx(i, j), 0)) ans++;
93+
}
94+
}
95+
return ans;
96+
}
97+
int[][] dirs = new int[][]{{1,0},{-1,0},{0,1},{0,-1}};
98+
void dfs(int x, int y) {
99+
union(getIdx(x, y), 0);
100+
for (int[] d : dirs) {
101+
int nx = x + d[0], ny = y + d[1];
102+
if (nx < 0 || nx >= m || ny < 0 || ny >= n) continue;
103+
if (g[nx][ny] != 1 || query(getIdx(nx, ny), 0)) continue;
104+
dfs(nx, ny);
105+
}
106+
}
107+
int getIdx(int x, int y) {
108+
return x * n + y + 1;
109+
}
110+
}
111+
```
112+
* 时间复杂度:初始化并查集复杂度为 $O(m * n)$;使用 `DFS` 对边缘陆地连通块进行标记复杂度为 $O(m * n)$;统计答案复杂度为 $O(m * n)$。整体复杂度为 $O(m * n)$
113+
* 空间复杂度:$O(m * n)$
114+
115+
---
116+
117+
### 最后
118+
119+
这是我们「刷穿 LeetCode」系列文章的第 `No.1011` 篇,系列开始于 2021年01月01日,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。
120+
121+
在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。
122+
123+
为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:https://github.com/SharingSource/LogicStack-LeetCode
124+
125+
在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。
126+

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /