Skip to content

Commit f4bc7ef

Browse files
author
lucifer
committed
feat: #1020
1 parent b9bb197 commit f4bc7ef

File tree

2 files changed

+160
-0
lines changed

2 files changed

+160
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,7 @@ leetcode 题解,记录自己的 leetcode 解题之路。
215215
- [0887.super-egg-drop](./problems/887.super-egg-drop.md)
216216
- [0900.rle-iterator](./problems/900.rle-iterator.md)
217217
- [0912.sort-an-array](./problems/912.sort-an-array.md) 🆕
218+
- [1020.number-of-enclaves.md](./problems/1020.number-of-enclaves.md) 🆕
218219
- [1023.camelcase-matching](./problems/1023.camelcase-matching.md) 🆕
219220
- [1031.maximum-sum-of-two-non-overlapping-subarrays](./problems/1031.maximum-sum-of-two-non-overlapping-subarrays.md)
220221
- [1186.maximum-subarray-sum-with-one-deletion](./problems/1186.maximum-subarray-sum-with-one-deletion.md) 🆕

problems/1020.number-of-enclaves.md

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
## 题目地址
2+
3+
https://leetcode-cn.com/problems/number-of-enclaves/
4+
5+
## 题目描述
6+
7+
```
8+
给出一个二维数组 A,每个单元格为 0(代表海)或 1(代表陆地)。
9+
10+
移动是指在陆地上从一个地方走到另一个地方(朝四个方向之一)或离开网格的边界。
11+
12+
返回网格中无法在任意次数的移动中离开网格边界的陆地单元格的数量。
13+
14+
 
15+
16+
示例 1:
17+
18+
输入:[[0,0,0,0],[1,0,1,0],[0,1,1,0],[0,0,0,0]]
19+
输出:3
20+
解释:
21+
有三个 1 被 0 包围。一个 1 没有被包围,因为它在边界上。
22+
示例 2:
23+
24+
输入:[[0,1,1,0],[0,0,1,0],[0,0,1,0],[0,0,0,0]]
25+
输出:0
26+
解释:
27+
所有 1 都在边界上或可以到达边界。
28+
 
29+
30+
提示:
31+
32+
1 <= A.length <= 500
33+
1 <= A[i].length <= 500
34+
0 <= A[i][j] <= 1
35+
所有行的大小都相同
36+
37+
```
38+
39+
## 解法一 (暴力法)
40+
41+
### 思路
42+
43+
这是一个典型的可以使用 DFS 进行解决的一类题目, LeetCode 相关的题目有很多。
44+
45+
对于这种题目不管是思路还是代码都有很大的相似性,我们来看下。
46+
47+
暴力法的思路很简单,我们遍历整个矩阵:
48+
49+
- 如果遍历到 0,我们不予理会
50+
- 如果遍历到 1. 我们将其加到 temp
51+
- 我们不断拓展边界(上下左右)
52+
- 如果 dfs 过程中碰到了边界,说明我们可以逃脱,我们将累加的 temp 清空
53+
- 如果 dfs 过程之后没有碰到边界,说明我们无法逃脱。我们将 temp 加到 cnt
54+
- 最终返回 cnt 即可
55+
56+
### 关键点解析
57+
58+
- visited 记录访问过的节点,防止重复计算
59+
60+
### 代码
61+
62+
```python
63+
class Solution:
64+
temp = 0
65+
meetEdge = False
66+
67+
def numEnclaves(self, A: List[List[int]]) -> int:
68+
cnt = 0
69+
m = len(A)
70+
n = len(A[0])
71+
visited = set()
72+
73+
def dfs(i, j):
74+
if i < 0 or i >= m or j < 0 or j >= n or (i, j) in visited:
75+
return
76+
visited.add((i, j))
77+
if A[i][j] == 1:
78+
self.temp += 1
79+
else:
80+
return
81+
if i == 0 or i == m - 1 or j == 0 or j == n - 1:
82+
self.meetEdge = True
83+
dfs(i + 1, j)
84+
dfs(i - 1, j)
85+
dfs(i, j + 1)
86+
dfs(i, j - 1)
87+
for i in range(m):
88+
for j in range(n):
89+
dfs(i, j)
90+
if not self.meetEdge:
91+
cnt += self.temp
92+
self.meetEdge = False
93+
self.temp = 0
94+
return cnt
95+
96+
```
97+
98+
## 解法二 (消除法)
99+
100+
### 思路
101+
102+
上面的解法时间复杂度和空间复杂度都很差,我们考虑进行优化, 这里我们使用消除法。
103+
104+
- 从矩阵边界开始 dfs
105+
- 如果碰到 1 就将其变成 0
106+
- 如果碰到 0 则什么都不做
107+
- 最后我们遍历整个矩阵,数一下 1 的个数即可。
108+
109+
### 关键点解析
110+
111+
- dfs 消除法
112+
113+
### 代码
114+
115+
```python
116+
#
117+
# @lc app=leetcode.cn id=1020 lang=python3
118+
#
119+
# [1020] 飞地的数量
120+
#
121+
122+
# @lc code=start
123+
124+
125+
class Solution:
126+
127+
def numEnclaves(self, A: List[List[int]]) -> int:
128+
cnt = 0
129+
m = len(A)
130+
n = len(A[0])
131+
132+
def dfs(i, j):
133+
if i < 0 or i >= m or j < 0 or j >= n or A[i][j] == 0:
134+
return
135+
A[i][j] = 0
136+
137+
dfs(i + 1, j)
138+
dfs(i - 1, j)
139+
dfs(i, j + 1)
140+
dfs(i, j - 1)
141+
for i in range(m):
142+
dfs(i, 0)
143+
dfs(i, n - 1)
144+
for j in range(1, n - 1):
145+
dfs(0, j)
146+
dfs(m - 1, j)
147+
for i in range(m):
148+
for j in range(n):
149+
if A[i][j] == 1:
150+
cnt += 1
151+
return cnt
152+
153+
# @lc code=end
154+
155+
```
156+
157+
## 参考
158+
159+
- [200.number-of-islands](https://github.com/azl397985856/leetcode/blob/master/problems/200.number-of-islands.md)

0 commit comments

Comments
 (0)