Skip to content

Commit 12eeb53

Browse files
committedSep 3, 2021
feat: add solutions to lc problem: No.0778.Swim in Rising Water
1 parent 30ecd18 commit 12eeb53

File tree

6 files changed

+555
-105
lines changed

6 files changed

+555
-105
lines changed
 

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

+225-44
Original file line numberDiff line numberDiff line change
@@ -51,19 +51,105 @@
5151
<li><code>grid[i][j]</code> 是 <code>[0, ..., N*N - 1]</code> 的排列。</li>
5252
</ol>
5353

54-
5554
## 解法
5655

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

58+
并查集。
59+
60+
模板 1——朴素并查集:
61+
62+
```python
63+
# 初始化,p存储每个点的父节点
64+
p = list(range(n))
65+
66+
# 返回x的祖宗节点
67+
def find(x):
68+
if p[x] != x:
69+
# 路径压缩
70+
p[x] = find(p[x])
71+
return p[x]
72+
73+
# 合并a和b所在的两个集合
74+
p[find(a)] = find(b)
75+
```
76+
77+
模板 2——维护 size 的并查集:
78+
79+
```python
80+
# 初始化,p存储每个点的父节点,size只有当节点是祖宗节点时才有意义,表示祖宗节点所在集合中,点的数量
81+
p = list(range(n))
82+
size = [1] * n
83+
84+
# 返回x的祖宗节点
85+
def find(x):
86+
if p[x] != x:
87+
# 路径压缩
88+
p[x] = find(p[x])
89+
return p[x]
90+
91+
# 合并a和b所在的两个集合
92+
if find(a) != find(b):
93+
size[find(b)] += size[find(a)]
94+
p[find(a)] = find(b)
95+
```
96+
97+
模板 3——维护到祖宗节点距离的并查集:
98+
99+
```python
100+
# 初始化,p存储每个点的父节点,d[x]存储x到p[x]的距离
101+
p = list(range(n))
102+
d = [0] * n
103+
104+
# 返回x的祖宗节点
105+
def find(x):
106+
if p[x] != x:
107+
t = find(p[x])
108+
d[x] += d[p[x]]
109+
p[x] = t
110+
return p[x]
111+
112+
# 合并a和b所在的两个集合
113+
p[find(a)] = find(b)
114+
d[find(a)] = distance
115+
```
116+
59117
<!-- tabs:start -->
60118

61119
### **Python3**
62120

63121
<!-- 这里可写当前语言的特殊实现逻辑 -->
64122

65123
```python
66-
124+
class Solution:
125+
def swimInWater(self, grid: List[List[int]]) -> int:
126+
n = len(grid)
127+
p = list(range(n * n))
128+
129+
def find(x):
130+
if p[x] != x:
131+
p[x] = find(p[x])
132+
return p[x]
133+
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+
140+
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
146+
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])
150+
if find(0) == find(n * n - 1):
151+
return h
152+
return -1
67153
```
68154

69155
### **Java**
@@ -72,54 +158,149 @@
72158

73159
```java
74160
class Solution {
75-
// x、y方向向量
76-
public static final int[] dx = {0, 0, 1, -1};
77-
public static final int[] dy = {1, -1, 0, 0};
78-
/**
79-
* https://blog.csdn.net/fuxuemingzhu/article/details/82926674
80-
* <p>
81-
* 参考这篇文章的第二种解题方法做的
82-
* <p>
83-
* 通过优先级队列找寻局部最优解 最终的得到的结果就是全局最优解
84-
*
85-
* @param grid
86-
* @return
87-
*/
88-
// 以grid左上角为原点,横向为X轴,纵向为Y轴
161+
private int[] p;
162+
private int n;
163+
private int[][] dirs = new int[][]{{0, -1}, {0, 1}, {1, 0}, {-1, 0}};
164+
89165
public int swimInWater(int[][] grid) {
90-
// 定义一个优先级队列 按照h从小到大排列
91-
Queue<Pair<Integer, Pair<Integer, Integer>>> queue = new PriorityQueue<>(Comparator.comparing(Pair::getKey));
92-
queue.add(new Pair<>(grid[0][0], new Pair<>(0, 0)));
93-
// 已经遍历过的点
94-
Set<Pair<Integer, Integer>> visitSet = new HashSet<>();
95-
visitSet.add(new Pair<>(0, 0));
96-
97-
int res = 0;
98-
int length = grid.length;
99-
100-
while (!queue.isEmpty()) {
101-
Pair<Integer, Pair<Integer, Integer>> top = queue.poll();
102-
Integer x = top.getValue().getKey();
103-
Integer y = top.getValue().getValue();
104-
res = Math.max(res, top.getKey());
105-
// 2 <= N <= 50 这个范围内可以直接使用==进行Integer的比较
106-
if (x == top.getValue().getValue() && y == length - 1) {
107-
break;
166+
n = grid.length;
167+
p = new int[n * n];
168+
for (int i = 0; i < p.length; ++i) {
169+
p[i] = i;
170+
}
171+
int[] hi = new int[n * n];
172+
for (int i = 0; i < n; ++i) {
173+
for (int j = 0; j < n; ++j) {
174+
hi[grid[i][j]] = index(i, j);
108175
}
109-
110-
for (int i = 0; i < 4; i++) {
111-
int newY = y + dy[i];
112-
int newX = x + dx[i];
113-
if (newX < 0 || newY < 0 || newX >= length || newY >= length || visitSet.contains(new Pair<>(newX, newY))) {
114-
// 直接忽略
115-
continue;
176+
}
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]);
183+
}
184+
if (find(0) == find(n * n - 1)) {
185+
return h;
116186
}
117-
queue.add(new Pair<>(grid[newX][newY], new Pair<>(newX, newY)));
118-
visitSet.add(new Pair<>(newX, newY));
119187
}
120188
}
121-
return res;
189+
return -1;
190+
}
191+
192+
private int find(int x) {
193+
if (p[x] != x) {
194+
p[x] = find(p[x]);
195+
}
196+
return p[x];
197+
}
198+
199+
private int index(int i, int j) {
200+
return i * n + j;
122201
}
202+
203+
private boolean check(int i, int j) {
204+
return i >= 0 && i < n && j >= 0 && j < n;
205+
}
206+
}
207+
```
208+
209+
### **C++**
210+
211+
```cpp
212+
class Solution {
213+
public:
214+
vector<int> p;
215+
int n;
216+
int dirs[4][2] = {{0, -1}, {0, 1}, {1, 0}, {-1, 0}};
217+
218+
int swimInWater(vector<vector<int>> &grid) {
219+
n = grid.size();
220+
for (int i = 0; i < n * n; ++i)
221+
p.push_back(i);
222+
vector<int> hi(n * n, 0);
223+
for (int i = 0; i < n; ++i)
224+
for (int j = 0; j < n; ++j)
225+
hi[grid[i][j]] = index(i, j);
226+
for (int h = 0; h < n * n; ++h)
227+
{
228+
int x = hi[h] / n, y = hi[h] % n;
229+
for (auto dir : dirs)
230+
{
231+
int x1 = x + dir[0], y1 = y + dir[1];
232+
if (check(x1, y1) && grid[x1][y1] <= h)
233+
p[find(index(x1, y1))] = find(hi[h]);
234+
if (find(0) == find(n * n - 1))
235+
return h;
236+
}
237+
}
238+
return -1;
239+
}
240+
241+
int find(int x) {
242+
if (p[x] != x)
243+
p[x] = find(p[x]);
244+
return p[x];
245+
}
246+
247+
int index(int i, int j) {
248+
return i * n + j;
249+
}
250+
251+
bool check(int i, int j) {
252+
return i >= 0 && i < n && j >= 0 && j < n;
253+
}
254+
};
255+
```
256+
257+
### **Go**
258+
259+
```go
260+
var p []int
261+
var n int
262+
263+
func swimInWater(grid [][]int) int {
264+
n = len(grid)
265+
p = make([]int, n*n)
266+
hi := make([]int, n*n)
267+
for i := 0; i < len(p); i++ {
268+
p[i] = i
269+
}
270+
for i := 0; i < n; i++ {
271+
for j := 0; j < n; j++ {
272+
hi[grid[i][j]] = index(i, j)
273+
}
274+
}
275+
dirs := [4][2]int{{0, -1}, {0, 1}, {1, 0}, {-1, 0}}
276+
for h := 0; h < n*n; h++ {
277+
x, y := hi[h]/n, hi[h]%n
278+
for _, dir := range dirs {
279+
x1, y1 := x+dir[0], y+dir[1]
280+
if check(x1, y1) && grid[x1][y1] <= h {
281+
p[find(index(x1, y1))] = find(hi[h])
282+
}
283+
if find(0) == find(n*n-1) {
284+
return h
285+
}
286+
}
287+
}
288+
return -1
289+
}
290+
291+
func find(x int) int {
292+
if p[x] != x {
293+
p[x] = find(p[x])
294+
}
295+
return p[x]
296+
}
297+
298+
func index(i, j int) int {
299+
return i*n + j
300+
}
301+
302+
func check(i, j int) bool {
303+
return i >= 0 && i < n && j >= 0 && j < n
123304
}
124305
```
125306

0 commit comments

Comments
 (0)