6
6
7
7
<!-- 这里写题目描述 -->
8
8
9
- <p >在一个 N x N 的坐标方格 < code >grid</code > 中,每一个方格的值 <code >grid[i][j]</code > 表示在位置 <code >(i,j)</code > 的平台高度。</p >
9
+ <p >在一个 < code >n x n</ code >& nbsp ; 的整数矩阵 & nbsp ; < code > grid</code > 中,每一个方格的值 <code >grid[i][j]</code > 表示位置 <code >(i, j)</code > 的平台高度。</p >
10
10
11
- <p >现在开始下雨了。当时间为 <code >t</code > 时,此时雨水导致水池中任意位置的水位为 <code >t</code > 。你可以从一个平台游向四周相邻的任意一个平台,但是前提是此时水位必须同时淹没这两个平台。假定你可以瞬间移动无限距离,也就是默认在方格内部游动是不耗时的。当然,在你游泳的时候你必须待在坐标方格里面。</p >
11
+ <p >当开始下雨时,在时间为 & nbsp ; <code >t</code >& nbsp ; 时,水池中的水位为 & nbsp ; <code >t</code >& nbsp ; 。你可以从一个平台游向四周相邻的任意一个平台,但是前提是此时水位必须同时淹没这两个平台。假定你可以瞬间移动无限距离,也就是默认在方格内部游动是不耗时的。当然,在你游泳的时候你必须待在坐标方格里面。</p >
12
12
13
- <p >你从坐标方格的左上平台 (0,0) 出发。最少耗时多久你才能到达坐标方格的右下平台 < code >(N -1, N -1)</code >? </p >
13
+ <p >你从坐标方格的左上平台& nbsp ; < code > (0,0)</ code > 出发。返回 < em >你到达坐标方格的右下平台 & nbsp ; < code >(n -1, n -1)</code >& nbsp ; 所需的最少时间 。</ em > </p >
14
14
15
- <p > </p >
15
+ <p >& nbsp ; </p >
16
16
17
17
<p ><strong >示例 1:</strong ></p >
18
18
19
+ <p ><img src =" https://cdn.jsdelivr.net/gh/doocs/leetcode@main/solution/0700-0799/0778.Swim%20in%20Rising%20Water/images/swim1-grid.jpg " /></p >
20
+
19
21
<pre >
20
- <strong >输入:</strong > [[0,2],[1,3]]
22
+ <strong >输入:</strong > grid = [[0,2],[1,3]]
21
23
<strong >输出:</strong > 3
22
24
<strong >解释:</strong >
23
25
时间为0时,你位于坐标方格的位置为 <code >(0, 0)。</code >
24
26
此时你不能游向任意方向,因为四个相邻方向平台的高度都大于当前时间为 0 时的水位。
25
-
26
27
等时间到达 3 时,你才可以游向平台 (1, 1). 因为此时的水位是 3,坐标方格中的平台没有比水位 3 更高的,所以你可以游向坐标方格中的任意位置
27
28
</pre >
28
29
29
- <p ><strong >示例2:</strong ></p >
30
+ <p ><strong >示例 2:</strong ></p >
31
+
32
+ <p ><img src =" https://cdn.jsdelivr.net/gh/doocs/leetcode@main/solution/0700-0799/0778.Swim%20in%20Rising%20Water/images/swim2-grid-1.jpg " /></p >
30
33
31
34
<pre >
32
- <strong >输入:</strong > [[0,1,2,3,4],[24,23,22,21,5],[12,13,14,15,16],[11,17,18,19,20],[10,9,8,7,6]]
35
+ <strong >输入:</strong > grid = [[0,1,2,3,4],[24,23,22,21,5],[12,13,14,15,16],[11,17,18,19,20],[10,9,8,7,6]]
33
36
<strong >输出:</strong > 16
34
- <strong >解释:</strong >
35
- <strong > 0 1 2 3 4</strong >
36
- 24 23 22 21 <strong >5</strong >
37
- <strong >12 13 14 15 16</strong >
38
- <strong >11</strong > 17 18 19 20
39
- <strong >10 9 8 7 6</strong >
40
-
41
- 最终的路线用加粗进行了标记。
37
+ <strong >解释: </strong >最终的路线用加粗进行了标记。
42
38
我们必须等到时间为 16,此时才能保证平台 (0, 0) 和 (4, 4) 是连通的
43
39
</pre >
44
40
45
- <p > </p >
41
+ <p >& nbsp ; </p >
46
42
47
43
<p ><strong >提示:</strong ></p >
48
44
49
- <ol >
50
- <li><code>2 <= N <= 50</code>.</li>
51
- <li><code>grid[i][j]</code> 是 <code>[0, ..., N*N - 1]</code> 的排列。</li>
52
- </ol >
45
+ <ul >
46
+ <li><code>n == grid.length</code></li>
47
+ <li><code>n == grid[i].length</code></li>
48
+ <li><code>1 <= n <= 50</code></li>
49
+ <li><code>0 <= grid[i][j] < n<sup>2</sup></code></li>
50
+ <li><code>grid[i][j]</code> 中每个值 <strong>均无重复</strong></li>
51
+ </ul >
53
52
54
53
## 解法
55
54
56
55
<!-- 这里可写通用的实现逻辑 -->
57
56
58
- 并查集。
57
+ 并查集。每经过一个时刻 t,找到此时和雨水高度相等的单元格 ` (i, j) ` ,如果与 ` (i, j) ` 相邻的单元格 ` (x, y) ` 满足高度不超过 t,则将这两个单元格进行合并。如果在某个时刻合并之后,单元格 ` (0, 0) ` 与单元格 ` (n - 1, n - 1) ` 连通,则返回该时刻。
58
+
59
+ 以下是并查集的几个常用模板。
59
60
60
61
模板 1——朴素并查集:
61
62
@@ -123,32 +124,25 @@ d[find(a)] = distance
123
124
``` python
124
125
class Solution :
125
126
def swimInWater (self , grid : List[List[int ]]) -> int :
126
- n = len (grid)
127
- p = list (range (n * n))
128
-
129
127
def find (x ):
130
128
if p[x] != x:
131
129
p[x] = find(p[x])
132
130
return p[x]
133
131
134
- def index (i , j ):
135
- return i * n + j
136
-
137
- def check (i , j ):
138
- return 0 <= i < n and 0 <= j < n
139
-
132
+ n = len (grid)
133
+ p = list (range (n * n))
140
134
hi = [0 ] * (n * n)
141
- for i in range (n ):
142
- for j in range (n ):
143
- hi[grid[i][j]] = index(i, j)
144
- for h in range (n * n):
145
- x, y = hi[h ] // n, hi[h ] % n
135
+ for i, row in enumerate (grid ):
136
+ for j, h in enumerate (row ):
137
+ hi[h] = i * n + j
138
+ for t in range (n * n):
139
+ i, j = hi[t ] // n, hi[t ] % n
146
140
for a, b in [(0 , - 1 ), (0 , 1 ), (1 , 0 ), (- 1 , 0 )]:
147
- x1, y1 = x + a, y + b
148
- if check(x1, y1) and grid[x1][y1 ] <= h :
149
- p[find(index(x1, y1)) ] = find(hi[h ])
141
+ x, y = i + a, j + b
142
+ if 0 <= x < n and 0 <= y < n and grid[x][y ] <= t :
143
+ p[find(x * n + y) ] = find(hi[t ])
150
144
if find(0 ) == find(n * n - 1 ):
151
- return h
145
+ return t
152
146
return - 1
153
147
```
154
148
@@ -159,30 +153,31 @@ class Solution:
159
153
``` java
160
154
class Solution {
161
155
private int [] p;
162
- private int n;
163
- private int [][] dirs = new int [][]{{0 , - 1 }, {0 , 1 }, {1 , 0 }, {- 1 , 0 }};
164
156
165
157
public int swimInWater (int [][] grid ) {
166
- n = grid. length;
158
+ int n = grid. length;
167
159
p = new int [n * n];
168
160
for (int i = 0 ; i < p. length; ++ i) {
169
161
p[i] = i;
170
162
}
171
163
int [] hi = new int [n * n];
172
164
for (int i = 0 ; i < n; ++ i) {
173
165
for (int j = 0 ; j < n; ++ j) {
174
- hi[grid[i][j]] = index(i, j) ;
166
+ hi[grid[i][j]] = i * n + j ;
175
167
}
176
168
}
177
- for (int h = 0 ; h < n * n; ++ h) {
178
- int x = hi[h] / n, y = hi[h] % n;
179
- for (int [] dir : dirs) {
180
- int x1 = x + dir[0 ], y1 = y + dir[1 ];
181
- if (check(x1, y1) && grid[x1][y1] <= h) {
182
- p[find(index(x1, y1))] = find(hi[h]);
169
+ int [] dirs = {- 1 , 0 , 1 , 0 , - 1 };
170
+ for (int t = 0 ; t < n * n; ++ t) {
171
+ int i = hi[t] / n;
172
+ int j = hi[t] % n;
173
+ for (int k = 0 ; k < 4 ; ++ k) {
174
+ int x = i + dirs[k];
175
+ int y = j + dirs[k + 1 ];
176
+ if (x >= 0 && x < n && y >= 0 && y < n && grid[x][y] <= t) {
177
+ p[find(x * n + y)] = find(i * n + j);
183
178
}
184
179
if (find(0 ) == find(n * n - 1 )) {
185
- return h ;
180
+ return t ;
186
181
}
187
182
}
188
183
}
@@ -195,14 +190,6 @@ class Solution {
195
190
}
196
191
return p[x];
197
192
}
198
-
199
- private int index (int i , int j ) {
200
- return i * n + j;
201
- }
202
-
203
- private boolean check (int i , int j ) {
204
- return i >= 0 && i < n && j >= 0 && j < n;
205
- }
206
193
}
207
194
```
208
195
@@ -246,96 +233,74 @@ function swimInWater(grid: number[][]): number {
246
233
class Solution {
247
234
public:
248
235
vector<int > p;
249
- int n;
250
- int dirs[ 4] [ 2 ] = {{0, -1}, {0, 1}, {1, 0}, {-1, 0}};
251
-
252
- int swimInWater(vector<vector<int>> &grid) {
253
- n = grid.size();
254
- for (int i = 0; i < n * n; ++i)
255
- p.push_back(i);
256
- vector<int> hi(n * n, 0);
236
+
237
+ int swimInWater(vector<vector<int>>& grid) {
238
+ int n = grid.size();
239
+ p.resize(n * n);
240
+ for (int i = 0; i < p.size(); ++i) p[i] = i;
241
+ vector<int> hi(n * n);
257
242
for (int i = 0; i < n; ++i)
258
243
for (int j = 0; j < n; ++j)
259
- hi[grid[i][j]] = index(i, j);
260
- for (int h = 0; h < n * n; ++h)
244
+ hi[grid[i][j]] = i * n + j;
245
+ vector<int> dirs = {-1, 0, 1, 0, -1};
246
+ for (int t = 0; t < n * n; ++t)
261
247
{
262
- int x = hi[h ] / n, y = hi[h ] % n;
263
- for (auto dir : dirs )
248
+ int i = hi[t ] / n, j = hi[t ] % n;
249
+ for (int k = 0; k < 4; ++k )
264
250
{
265
- int x1 = x + dir[0], y1 = y + dir[1];
266
- if (check(x1, y1) && grid[x1][y1] <= h)
267
- p[find(index(x1, y1))] = find(hi[h]);
268
- if (find(0) == find(n * n - 1))
269
- return h;
251
+ int x = i + dirs[k], y = j + dirs[k + 1];
252
+ if (x >= 0 && x < n && y >= 0 && y < n && grid[x][y] <= t)
253
+ p[find(x * n + y)] = find(hi[t]);
254
+ if (find(0) == find(n * n - 1)) return t;
270
255
}
271
256
}
272
257
return -1 ;
273
258
}
274
259
275
260
int find (int x) {
276
- if (p[ x] != x)
277
- p[ x] = find(p[ x] );
261
+ if (p[ x] != x) p[ x] = find(p[ x] );
278
262
return p[ x] ;
279
263
}
280
-
281
- int index(int i, int j) {
282
- return i * n + j;
283
- }
284
-
285
- bool check(int i, int j) {
286
- return i >= 0 && i < n && j >= 0 && j < n;
287
- }
288
264
};
289
265
```
290
266
291
267
### **Go**
292
268
293
269
```go
294
- var p []int
295
- var n int
296
-
297
270
func swimInWater(grid [][]int) int {
298
- n = len(grid)
299
- p = make([]int, n*n)
300
- hi := make([]int, n*n)
301
- for i := 0; i < len(p); i++ {
271
+ n := len(grid)
272
+ p := make([]int, n*n)
273
+ for i := range p {
302
274
p[i] = i
303
275
}
304
- for i := 0; i < n; i++ {
305
- for j := 0; j < n; j++ {
306
- hi[grid[i][j]] = index(i, j)
276
+ hi := make([]int, n*n)
277
+ for i, row := range grid {
278
+ for j, h := range row {
279
+ hi[h] = i*n + j
307
280
}
308
281
}
309
- dirs := [4][2]int{{0, -1}, {0, 1}, {1, 0}, {-1, 0}}
310
- for h := 0; h < n*n; h++ {
311
- x, y := hi[h]/n, hi[h]%n
312
- for _, dir := range dirs {
313
- x1, y1 := x+dir[0], y+dir[1]
314
- if check(x1, y1) && grid[x1][y1] <= h {
315
- p[find(index(x1, y1))] = find(hi[h])
282
+ var find func(x int) int
283
+ find = func(x int) int {
284
+ if p[x] != x {
285
+ p[x] = find(p[x])
286
+ }
287
+ return p[x]
288
+ }
289
+ dirs := []int{-1, 0, 1, 0, -1}
290
+ for t := 0; t < n*n; t++ {
291
+ i, j := hi[t]/n, hi[t]%n
292
+ for k := 0; k < 4; k++ {
293
+ x, y := i+dirs[k], j+dirs[k+1]
294
+ if x >= 0 && x < n && y >= 0 && y < n && grid[x][y] <= t {
295
+ p[find(x*n+y)] = find(hi[t])
316
296
}
317
297
if find(0) == find(n*n-1) {
318
- return h
298
+ return t
319
299
}
320
300
}
321
301
}
322
302
return -1
323
303
}
324
-
325
- func find(x int) int {
326
- if p[x] != x {
327
- p[x] = find(p[x])
328
- }
329
- return p[x]
330
- }
331
-
332
- func index(i, j int) int {
333
- return i*n + j
334
- }
335
-
336
- func check(i, j int) bool {
337
- return i >= 0 && i < n && j >= 0 && j < n
338
- }
339
304
```
340
305
341
306
### ** ...**
0 commit comments