Skip to content

Commit 8f31ada

Browse files
committed
feat: update solutions to lc problem: No.0305
No.0305.Number of Islands II
1 parent 9dc29fe commit 8f31ada

File tree

17 files changed

+868
-284
lines changed

17 files changed

+868
-284
lines changed

solution/0300-0399/0305.Number of Islands II/README.md

Lines changed: 103 additions & 131 deletions
Original file line numberDiff line numberDiff line change
@@ -6,62 +6,50 @@
66

77
<!-- 这里写题目描述 -->
88

9-
<p>假设你设计一个游戏,用一个&nbsp;<code>m</code>&nbsp;&nbsp;<code>n</code>&nbsp;列的&nbsp;2D 网格来存储你的游戏地图。</p>
10-
11-
<p>起始的时候,每个格子的地形都被默认标记为「水」。我们可以通过使用&nbsp;<code>addLand</code>&nbsp;进行操作,将位置 <code>(row, col)</code> 的「水」变成「陆地」。</p>
12-
13-
<p>你将会被给定一个列表,来记录所有需要被操作的位置,然后你需要返回计算出来&nbsp;<strong>每次&nbsp;<em>addLand </em>操作后岛屿的数量</strong>。</p>
14-
15-
<p>注意:一个岛的定义是被「水」包围的「陆地」,通过水平方向或者垂直方向上相邻的陆地连接而成。你可以假设地图网格的四边均被无边无际的「水」所包围。</p>
16-
17-
<p>请仔细阅读下方示例与解析,更加深入了解岛屿的判定。</p>
18-
19-
<p><strong>示例:</strong></p>
20-
21-
<pre><strong>输入:</strong> m = 3, n = 3, positions = [[0,0], [0,1], [1,2], [2,1]]
22-
<strong>输出:</strong> [1,1,2,3]
23-
</pre>
24-
25-
<p><strong>解析:</strong></p>
26-
27-
<p>起初,二维网格&nbsp;<code>grid</code>&nbsp;被全部注入「水」。(0 代表「水」,1 代表「陆地」)</p>
28-
29-
<pre>0 0 0
30-
0 0 0
31-
0 0 0
9+
<p>给你一个大小为 <code>m x n</code> 的二进制网格 <code>grid</code> 。网格表示一个地图,其中,<code>0</code> 表示水,<code>1</code> 表示陆地。最初,<code>grid</code> 中的所有单元格都是水单元格(即,所有单元格都是 <code>0</code>)。</p>
10+
11+
<p>可以通过执行 <code>addLand</code> 操作,将某个位置的水转换成陆地。给你一个数组 <code>positions</code> ,其中 <code>positions[i] = [r<sub>i</sub>, c<sub>i</sub>]</code> 是要执行第 <code>i</code> 次操作的位置 <code>(r<sub>i</sub>, c<sub>i</sub>)</code> 。</p>
12+
13+
<p>返回一个整数数组 <code>answer</code> ,其中 <code>answer[i]</code> 是将单元格 <code>(r<sub>i</sub>, c<sub>i</sub>)</code> 转换为陆地后,地图中岛屿的数量。</p>
14+
15+
<p><strong>岛屿</strong> 的定义是被「水」包围的「陆地」,通过水平方向或者垂直方向上相邻的陆地连接而成。你可以假设地图网格的四边均被无边无际的「水」所包围。</p>
16+
&nbsp;
17+
18+
<p><strong>示例 1:</strong></p>
19+
<img alt="" src="https://assets.leetcode.com/uploads/2021/03/10/tmp-grid.jpg" style="width: 500px; height: 294px;" />
20+
<pre>
21+
<strong>输入:</strong>m = 3, n = 3, positions = [[0,0],[0,1],[1,2],[2,1]]
22+
<strong>输出:</strong>[1,1,2,3]
23+
<strong>解释:</strong>
24+
起初,二维网格&nbsp;<code>grid</code>&nbsp;被全部注入「水」。(0 代表「水」,1 代表「陆地」)
25+
- 操作&nbsp;#1:<code>addLand(0, 0)</code> 将&nbsp;<code>grid[0][0]</code> 的水变为陆地。此时存在 1 个岛屿。
26+
- 操作&nbsp;#2:<code>addLand(0, 1)</code> 将&nbsp;<code>grid[0][1]</code> 的水变为陆地。此时存在 1 个岛屿。
27+
- 操作&nbsp;#3:<code>addLand(1, 2)</code> 将&nbsp;<code>grid[1][2]</code> 的水变为陆地。此时存在 2 个岛屿。
28+
- 操作&nbsp;#4:<code>addLand(2, 1)</code> 将&nbsp;<code>grid[2][1]</code> 的水变为陆地。此时存在 3 个岛屿。
3229
</pre>
3330

34-
<p>操作&nbsp;#1:<code>addLand(0, 0)</code> 将&nbsp;<code>grid[0][0]</code> 的水变为陆地。</p>
31+
<p><strong>示例 2:</strong></p>
3532

36-
<pre>1 0 0
37-
0 0 0 Number of islands = 1
38-
0 0 0
33+
<pre>
34+
<strong>输入:</strong>m = 1, n = 1, positions = [[0,0]]
35+
<strong>输出:</strong>[1]
3936
</pre>
4037

41-
<p>操作&nbsp;#2:<code>addLand(0, 1)</code> 将&nbsp;<code>grid[0][1]</code> 的水变为陆地。</p>
38+
<p>&nbsp;</p>
4239

43-
<pre>1 1 0
44-
0 0 0 岛屿的数量为 1
45-
0 0 0
46-
</pre>
40+
<p><strong>提示:</strong></p>
4741

48-
<p>操作&nbsp;#3:<code>addLand(1, 2)</code> 将&nbsp;<code>grid[1][2]</code> 的水变为陆地。</p>
42+
<ul>
43+
<li><code>1 &lt;= m, n, positions.length &lt;= 10<sup>4</sup></code></li>
44+
<li><code>1 &lt;= m * n &lt;= 10<sup>4</sup></code></li>
45+
<li><code>positions[i].length == 2</code></li>
46+
<li><code>0 &lt;= r<sub>i</sub> &lt; m</code></li>
47+
<li><code>0 &lt;= c<sub>i</sub> &lt; n</code></li>
48+
</ul>
4949

50-
<pre>1 1 0
51-
0 0 1 岛屿的数量为 2
52-
0 0 0
53-
</pre>
50+
<p>&nbsp;</p>
5451

55-
<p>操作&nbsp;#4:<code>addLand(2, 1)</code> 将&nbsp;<code>grid[2][1]</code> 的水变为陆地。</p>
56-
57-
<pre>1 1 0
58-
0 0 1 岛屿的数量为 3
59-
0 1 0
60-
</pre>
61-
62-
<p><strong>拓展:</strong></p>
63-
64-
<p>你是否能在 O(k log mn) 的时间复杂度程度内完成每次的计算?(k 表示&nbsp;<code>positions</code>&nbsp;的长度)</p>
52+
<p><strong>进阶:</strong>你可以设计一个时间复杂度 <code>O(k log(mn))</code> 的算法解决此问题吗?(其中 <code>k == positions.length</code>)</p>
6553

6654
## 解法
6755

@@ -137,31 +125,28 @@ d[find(a)] = distance
137125
```python
138126
class Solution:
139127
def numIslands2(self, m: int, n: int, positions: List[List[int]]) -> List[int]:
140-
p = list(range(m * n))
141-
grid = [[0] * n for _ in range(m)]
142-
143-
def check(i, j):
144-
return 0 <= i < m and 0 <= j < n and grid[i][j] == 1
145-
146128
def find(x):
147129
if p[x] != x:
148130
p[x] = find(p[x])
149131
return p[x]
150132

151-
res = []
152-
cur = 0
133+
grid = [[0] * n for _ in range(m)]
134+
cnt = 0
135+
p = list(range(m * n))
136+
ans = []
153137
for i, j in positions:
154138
if grid[i][j] == 1:
155-
res.append(cur)
139+
ans.append(cnt)
156140
continue
157141
grid[i][j] = 1
158-
cur += 1
159-
for x, y in [(-1, 0), (1, 0), (0, -1), (0, 1)]:
160-
if check(i + x, j + y) and find(i * n + j) != find((i + x) * n + j + y):
161-
p[find(i * n + j)] = find((i + x) * n + j + y)
162-
cur -= 1
163-
res.append(cur)
164-
return res
142+
cnt += 1
143+
for a, b in [[0, -1], [0, 1], [1, 0], [-1, 0]]:
144+
x, y = i + a, j + b
145+
if 0 <= x < m and 0 <= y < n and grid[x][y] == 1 and find(i * n + j) != find(x * n + y):
146+
p[find(i * n + j)] = find(x * n + y)
147+
cnt -= 1
148+
ans.append(cnt)
149+
return ans
165150
```
166151

167152
### **Java**
@@ -171,42 +156,36 @@ class Solution:
171156
```java
172157
class Solution {
173158
private int[] p;
174-
private int[][] dirs = new int[][]{{0, -1}, {0, 1}, {1, 0}, {-1, 0}};
175-
private int[][] grid;
176-
private int m;
177-
private int n;
178159

179160
public List<Integer> numIslands2(int m, int n, int[][] positions) {
180161
p = new int[m * n];
181162
for (int i = 0; i < p.length; ++i) {
182163
p[i] = i;
183164
}
184-
grid = new int[m][n];
185-
this.m = m;
186-
this.n = n;
187-
List<Integer> res = new ArrayList<>();
188-
int cur = 0;
189-
for (int[] position : positions) {
190-
int i = position[0], j = position[1];
165+
int[][] grid = new int[m][n];
166+
int cnt = 0;
167+
List<Integer> ans = new ArrayList<>();
168+
int[] dirs = {-1, 0, 1, 0, -1};
169+
for (int[] pos : positions) {
170+
int i = pos[0];
171+
int j = pos[1];
191172
if (grid[i][j] == 1) {
192-
res.add(cur);
173+
ans.add(cnt);
193174
continue;
194175
}
195176
grid[i][j] = 1;
196-
++cur;
197-
for (int[] e : dirs) {
198-
if (check(i + e[0], j + e[1]) && find(i * n + j) != find((i + e[0]) * n + j + e[1])) {
199-
p[find(i * n + j)] = find((i + e[0]) * n + j + e[1]);
200-
--cur;
177+
++cnt;
178+
for (int k = 0; k < 4; ++k) {
179+
int x = i + dirs[k];
180+
int y = j + dirs[k + 1];
181+
if (x >= 0 && x < m && y >= 0 && y < n && grid[x][y] == 1 && find(x * n + y) != find(i * n + j)) {
182+
p[find(x * n + y)] = find(i * n + j);
183+
--cnt;
201184
}
202185
}
203-
res.add(cur);
186+
ans.add(cnt);
204187
}
205-
return res;
206-
}
207-
208-
private boolean check(int i, int j) {
209-
return i >= 0 && i < m && j >= 0 && j < n && grid[i][j] == 1;
188+
return ans;
210189
}
211190

212191
private int find(int x) {
@@ -224,38 +203,36 @@ class Solution {
224203
class Solution {
225204
public:
226205
vector<int> p;
227-
int dirs[4][2] = {{0, -1}, {0, 1}, {1, 0}, {-1, 0}};
228206

229207
vector<int> numIslands2(int m, int n, vector<vector<int>>& positions) {
230208
p.resize(m * n);
231209
for (int i = 0; i < p.size(); ++i) p[i] = i;
232-
vector<vector<int>> grid(m, vector<int>(n, 0));
233-
vector<int> res;
234-
int cur = 0;
235-
for (auto position : positions)
210+
vector<vector<int>> grid(m, vector<int>(n));
211+
vector<int> ans;
212+
int cnt = 0;
213+
vector<int> dirs = {-1, 0, 1, 0, -1};
214+
for (auto& pos : positions)
236215
{
237-
int i = position[0], j = position[1];
216+
int i = pos[0], j = pos[1];
238217
if (grid[i][j] == 1)
239218
{
240-
res.push_back(cur);
219+
ans.push_back(cnt);
241220
continue;
242221
}
243222
grid[i][j] = 1;
244-
++cur;
245-
for (auto e : dirs) {
246-
if (check(i + e[0], j + e[1], grid) && find(i * n + j) != find((i + e[0]) * n + j + e[1]))
223+
++cnt;
224+
for (int k = 0; k < 4; ++k)
225+
{
226+
int x = i + dirs[k], y = j + dirs[k + 1];
227+
if (x >= 0 && x < m && y >= 0 && y < n && grid[x][y] == 1 && find(x * n + y) != find(i * n + j))
247228
{
248-
p[find(i * n + j)] = find((i + e[0]) * n + j + e[1]);
249-
--cur;
229+
p[find(x * n + y)] = find(i * n + j);
230+
--cnt;
250231
}
251232
}
252-
res.push_back(cur);
233+
ans.push_back(cnt);
253234
}
254-
return res;
255-
}
256-
257-
bool check(int i, int j, vector<vector<int>>& grid) {
258-
return i >= 0 && i < grid.size() && j >= 0 && j < grid[0].size() && grid[i][j] == 1;
235+
return ans;
259236
}
260237

261238
int find(int x) {
@@ -268,48 +245,43 @@ public:
268245
### **Go**
269246

270247
```go
271-
var p []int
272-
273248
func numIslands2(m int, n int, positions [][]int) []int {
274-
p = make([]int, m*n)
249+
p := make([]int, m*n)
275250
for i := 0; i < len(p); i++ {
276251
p[i] = i
277252
}
278253
grid := make([][]int, m)
279254
for i := 0; i < m; i++ {
280255
grid[i] = make([]int, n)
281256
}
282-
var res []int
283-
cur := 0
284-
dirs := [4][2]int{{0, -1}, {0, 1}, {1, 0}, {-1, 0}}
285-
for _, position := range positions {
286-
i, j := position[0], position[1]
257+
var find func(x int) int
258+
find = func(x int) int {
259+
if p[x] != x {
260+
p[x] = find(p[x])
261+
}
262+
return p[x]
263+
}
264+
var ans []int
265+
cnt := 0
266+
dirs := []int{-1, 0, 1, 0, -1}
267+
for _, pos := range positions {
268+
i, j := pos[0], pos[1]
287269
if grid[i][j] == 1 {
288-
res = append(res, cur)
270+
ans = append(ans, cnt)
289271
continue
290272
}
291273
grid[i][j] = 1
292-
cur++
293-
for _, e := range dirs {
294-
if check(i+e[0], j+e[1], grid) && find(i*n+j) != find((i+e[0])*n+j+e[1]) {
295-
p[find(i*n+j)] = find((i+e[0])*n + j + e[1])
296-
cur--
274+
cnt++
275+
for k := 0; k < 4; k++ {
276+
x, y := i+dirs[k], j+dirs[k+1]
277+
if x >= 0 && x < m && y >= 0 && y < n && grid[x][y] == 1 && find(x*n+y) != find(i*n+j) {
278+
p[find(x*n+y)] = find(i*n + j)
279+
cnt--
297280
}
298281
}
299-
res = append(res, cur)
300-
}
301-
return res
302-
}
303-
304-
func check(i, j int, grid [][]int) bool {
305-
return i >= 0 && i < len(grid) && j >= 0 && j < len(grid[0]) && grid[i][j] == 1
306-
}
307-
308-
func find(x int) int {
309-
if p[x] != x {
310-
p[x] = find(p[x])
282+
ans = append(ans, cnt)
311283
}
312-
return p[x]
284+
return ans
313285
}
314286
```
315287

0 commit comments

Comments
 (0)