6
6
7
7
<!-- 这里写题目描述 -->
8
8
9
- <p >假设你设计一个游戏,用一个  ; <code >m</code >  ; 行  ; <code >n</code >  ; 列的  ; 2D 网格来存储你的游戏地图。</p >
10
-
11
- <p >起始的时候,每个格子的地形都被默认标记为「水」。我们可以通过使用  ; <code >addLand</code >  ; 进行操作,将位置 <code >(row, col)</code > 的「水」变成「陆地」。</p >
12
-
13
- <p >你将会被给定一个列表,来记录所有需要被操作的位置,然后你需要返回计算出来  ; <strong >每次  ; <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 >起初,二维网格  ; <code >grid</code >  ; 被全部注入「水」。(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
+   ;
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
+ 起初,二维网格  ; <code >grid</code >  ; 被全部注入「水」。(0 代表「水」,1 代表「陆地」)
25
+ - 操作  ; #1:<code >addLand(0, 0)</code > 将  ; <code >grid[0][0]</code > 的水变为陆地。此时存在 1 个岛屿。
26
+ - 操作  ; #2:<code >addLand(0, 1)</code > 将  ; <code >grid[0][1]</code > 的水变为陆地。此时存在 1 个岛屿。
27
+ - 操作  ; #3:<code >addLand(1, 2)</code > 将  ; <code >grid[1][2]</code > 的水变为陆地。此时存在 2 个岛屿。
28
+ - 操作  ; #4:<code >addLand(2, 1)</code > 将  ; <code >grid[2][1]</code > 的水变为陆地。此时存在 3 个岛屿。
32
29
</pre >
33
30
34
- <p >操作 & nbsp ; #1:< code >addLand(0, 0)</ code > 将 & nbsp ; < code >grid[0][0]</ code > 的水变为陆地。 </p >
31
+ <p >< strong >示例 2:</ strong > </p >
35
32
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]
39
36
</pre >
40
37
41
- <p >操作   ; #2:< code >addLand(0, 1)</ code > 将 & nbsp ; < code >grid[0][1]</ code > 的水变为陆地。 </p >
38
+ <p >  ; </p >
42
39
43
- <pre >1 1 0
44
- 0 0 0 岛屿的数量为 1
45
- 0 0 0
46
- </pre >
40
+ <p ><strong >提示:</strong ></p >
47
41
48
- <p >操作  ; #3:<code >addLand(1, 2)</code > 将  ; <code >grid[1][2]</code > 的水变为陆地。</p >
42
+ <ul >
43
+ <li><code>1 <= m, n, positions.length <= 10<sup>4</sup></code></li>
44
+ <li><code>1 <= m * n <= 10<sup>4</sup></code></li>
45
+ <li><code>positions[i].length == 2</code></li>
46
+ <li><code>0 <= r<sub>i</sub> < m</code></li>
47
+ <li><code>0 <= c<sub>i</sub> < n</code></li>
48
+ </ul >
49
49
50
- <pre >1 1 0
51
- 0 0 1 岛屿的数量为 2
52
- 0 0 0
53
- </pre >
50
+ <p >  ; </p >
54
51
55
- <p >操作  ; #4:<code >addLand(2, 1)</code > 将  ; <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 表示  ; <code >positions</code >  ; 的长度)</p >
52
+ <p ><strong >进阶:</strong >你可以设计一个时间复杂度 <code >O(k log(mn))</code > 的算法解决此问题吗?(其中 <code >k == positions.length</code >)</p >
65
53
66
54
## 解法
67
55
@@ -137,31 +125,28 @@ d[find(a)] = distance
137
125
``` python
138
126
class Solution :
139
127
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
-
146
128
def find (x ):
147
129
if p[x] != x:
148
130
p[x] = find(p[x])
149
131
return p[x]
150
132
151
- res = []
152
- cur = 0
133
+ grid = [[0 ] * n for _ in range (m)]
134
+ cnt = 0
135
+ p = list (range (m * n))
136
+ ans = []
153
137
for i, j in positions:
154
138
if grid[i][j] == 1 :
155
- res .append(cur )
139
+ ans .append(cnt )
156
140
continue
157
141
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
165
150
```
166
151
167
152
### ** Java**
@@ -171,42 +156,36 @@ class Solution:
171
156
``` java
172
157
class Solution {
173
158
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;
178
159
179
160
public List<Integer > numIslands2 (int m , int n , int [][] positions ) {
180
161
p = new int [m * n];
181
162
for (int i = 0 ; i < p. length; ++ i) {
182
163
p[i] = i;
183
164
}
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 ];
191
172
if (grid[i][j] == 1 ) {
192
- res . add(cur );
173
+ ans . add(cnt );
193
174
continue ;
194
175
}
195
176
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;
201
184
}
202
185
}
203
- res . add(cur );
186
+ ans . add(cnt );
204
187
}
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;
210
189
}
211
190
212
191
private int find (int x ) {
@@ -224,38 +203,36 @@ class Solution {
224
203
class Solution {
225
204
public:
226
205
vector<int > p;
227
- int dirs[ 4] [ 2 ] = {{0, -1}, {0, 1}, {1, 0}, {-1, 0}};
228
206
229
207
vector<int> numIslands2(int m, int n, vector<vector<int>>& positions) {
230
208
p.resize(m * n);
231
209
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)
236
215
{
237
- int i = position [0], j = position [1];
216
+ int i = pos [0], j = pos [1];
238
217
if (grid[i][j] == 1)
239
218
{
240
- res .push_back(cur );
219
+ ans .push_back(cnt );
241
220
continue;
242
221
}
243
222
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))
247
228
{
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 ;
250
231
}
251
232
}
252
- res .push_back(cur );
233
+ ans .push_back(cnt );
253
234
}
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;
259
236
}
260
237
261
238
int find(int x) {
@@ -268,48 +245,43 @@ public:
268
245
### ** Go**
269
246
270
247
``` go
271
- var p []int
272
-
273
248
func numIslands2 (m int , n int , positions [][]int ) []int {
274
- p = make ([]int , m*n)
249
+ p : = make ([]int , m*n)
275
250
for i := 0 ; i < len (p); i++ {
276
251
p[i] = i
277
252
}
278
253
grid := make ([][]int , m)
279
254
for i := 0 ; i < m; i++ {
280
255
grid[i] = make ([]int , n)
281
256
}
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 ]
287
269
if grid[i][j] == 1 {
288
- res = append (res, cur )
270
+ ans = append (ans, cnt )
289
271
continue
290
272
}
291
273
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--
297
280
}
298
281
}
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)
311
283
}
312
- return p[x]
284
+ return ans
313
285
}
314
286
```
315
287
0 commit comments