Skip to content

Commit b504d1f

Browse files
committed
feat: add solutions to lc problem: No.0778
No.0778.Swim in Rising Water
1 parent 7f1dd0f commit b504d1f

File tree

10 files changed

+330
-441
lines changed

10 files changed

+330
-441
lines changed

solution/0700-0799/0778.Swim in Rising Water/README.md

Lines changed: 84 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -6,56 +6,57 @@
66

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

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>
1010

11-
<p>现在开始下雨了。当时间为 <code>t</code> 时,此时雨水导致水池中任意位置的水位为 <code>t</code> 。你可以从一个平台游向四周相邻的任意一个平台,但是前提是此时水位必须同时淹没这两个平台。假定你可以瞬间移动无限距离,也就是默认在方格内部游动是不耗时的。当然,在你游泳的时候你必须待在坐标方格里面。</p>
11+
<p>当开始下雨时,在时间为&nbsp;<code>t</code>&nbsp;时,水池中的水位为&nbsp;<code>t</code>&nbsp;。你可以从一个平台游向四周相邻的任意一个平台,但是前提是此时水位必须同时淹没这两个平台。假定你可以瞬间移动无限距离,也就是默认在方格内部游动是不耗时的。当然,在你游泳的时候你必须待在坐标方格里面。</p>
1212

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>
1414

15-
<p> </p>
15+
<p>&nbsp;</p>
1616

1717
<p><strong>示例 1:</strong></p>
1818

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+
1921
<pre>
20-
<strong>输入:</strong> [[0,2],[1,3]]
22+
<strong>输入:</strong> grid = [[0,2],[1,3]]
2123
<strong>输出:</strong> 3
2224
<strong>解释:</strong>
2325
时间为0时,你位于坐标方格的位置为 <code>(0, 0)。</code>
2426
此时你不能游向任意方向,因为四个相邻方向平台的高度都大于当前时间为 0 时的水位。
25-
2627
等时间到达 3 时,你才可以游向平台 (1, 1). 因为此时的水位是 3,坐标方格中的平台没有比水位 3 更高的,所以你可以游向坐标方格中的任意位置
2728
</pre>
2829

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>
3033

3134
<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]]
3336
<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>最终的路线用加粗进行了标记。
4238
我们必须等到时间为 16,此时才能保证平台 (0, 0) 和 (4, 4) 是连通的
4339
</pre>
4440

45-
<p> </p>
41+
<p>&nbsp;</p>
4642

4743
<p><strong>提示:</strong></p>
4844

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 &lt;= n &lt;= 50</code></li>
49+
<li><code>0 &lt;= grid[i][j] &lt;&nbsp;n<sup>2</sup></code></li>
50+
<li><code>grid[i][j]</code>&nbsp;中每个值&nbsp;<strong>均无重复</strong></li>
51+
</ul>
5352

5453
## 解法
5554

5655
<!-- 这里可写通用的实现逻辑 -->
5756

58-
并查集。
57+
并查集。每经过一个时刻 t,找到此时和雨水高度相等的单元格 `(i, j)`,如果与 `(i, j)` 相邻的单元格 `(x, y)` 满足高度不超过 t,则将这两个单元格进行合并。如果在某个时刻合并之后,单元格 `(0, 0)` 与单元格 `(n - 1, n - 1)` 连通,则返回该时刻。
58+
59+
以下是并查集的几个常用模板。
5960

6061
模板 1——朴素并查集:
6162

@@ -123,32 +124,25 @@ d[find(a)] = distance
123124
```python
124125
class Solution:
125126
def swimInWater(self, grid: List[List[int]]) -> int:
126-
n = len(grid)
127-
p = list(range(n * n))
128-
129127
def find(x):
130128
if p[x] != x:
131129
p[x] = find(p[x])
132130
return p[x]
133131

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))
140134
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
146140
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])
150144
if find(0) == find(n * n - 1):
151-
return h
145+
return t
152146
return -1
153147
```
154148

@@ -159,30 +153,31 @@ class Solution:
159153
```java
160154
class Solution {
161155
private int[] p;
162-
private int n;
163-
private int[][] dirs = new int[][]{{0, -1}, {0, 1}, {1, 0}, {-1, 0}};
164156

165157
public int swimInWater(int[][] grid) {
166-
n = grid.length;
158+
int n = grid.length;
167159
p = new int[n * n];
168160
for (int i = 0; i < p.length; ++i) {
169161
p[i] = i;
170162
}
171163
int[] hi = new int[n * n];
172164
for (int i = 0; i < n; ++i) {
173165
for (int j = 0; j < n; ++j) {
174-
hi[grid[i][j]] = index(i, j);
166+
hi[grid[i][j]] = i * n + j;
175167
}
176168
}
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);
183178
}
184179
if (find(0) == find(n * n - 1)) {
185-
return h;
180+
return t;
186181
}
187182
}
188183
}
@@ -195,14 +190,6 @@ class Solution {
195190
}
196191
return p[x];
197192
}
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-
}
206193
}
207194
```
208195

@@ -246,96 +233,74 @@ function swimInWater(grid: number[][]): number {
246233
class Solution {
247234
public:
248235
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);
257242
for (int i = 0; i < n; ++i)
258243
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)
261247
{
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)
264250
{
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;
270255
}
271256
}
272257
return -1;
273258
}
274259

275260
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]);
278262
return p[x];
279263
}
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-
}
288264
};
289265
```
290266
291267
### **Go**
292268
293269
```go
294-
var p []int
295-
var n int
296-
297270
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 {
302274
p[i] = i
303275
}
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
307280
}
308281
}
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])
316296
}
317297
if find(0) == find(n*n-1) {
318-
return h
298+
return t
319299
}
320300
}
321301
}
322302
return -1
323303
}
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-
}
339304
```
340305

341306
### **...**

0 commit comments

Comments
 (0)