Skip to content

Commit 40f0692

Browse files
authored
Update 778._Swim_in_Rising_Water.md
1 parent 0d38bc3 commit 40f0692

File tree

1 file changed

+124
-1
lines changed

1 file changed

+124
-1
lines changed

docs/Leetcode_Solutions/Python/778._Swim_in_Rising_Water.md

Lines changed: 124 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ grid[i][j] is a permutation of [0, ..., N*N - 1].
5353

5454

5555

56-
DFS + priority queue, beats 70.37%
56+
priority queue, beats 70.37%
5757

5858
```python
5959
class Solution:
@@ -75,6 +75,129 @@ class Solution:
7575
```
7676

7777

78+
> 思路 2
79+
******- 时间复杂度: O(N^3)******- 空间复杂度: O(N^2)******
80+
81+
82+
83+
union-find, 每隔一秒,我们就可以到达当前最大高度的那个点(即高度为time的那个点),然后从这个点继续往外走,如果旁边的点的高度小于等于time的话就可以走
84+
85+
每走一步time就加一秒,什么时候0和N^2-1相连了,就说明从(0,0)可以走到(N-1, N-1)了,此时返回time, beats 36.11%
86+
87+
```python
88+
class UnionFind(object):
89+
def __init__(self, n): # 初始化uf数组和组数目
90+
self.count = n
91+
self.uf = [i for i in range(n)]
92+
self.size = [1] * n # 每个联通分量的size
93+
94+
def find(self, x): # 判断节点所属于的组
95+
while x != self.uf[x]:
96+
self.uf[x] = self.uf[self.uf[x]]
97+
x = self.uf[x]
98+
return self.uf[x]
99+
100+
def union(self, x, y): # 连接两个节点
101+
x_root = self.find(x)
102+
y_root = self.find(y)
103+
if x_root == y_root:
104+
return
105+
if self.size[x_root] < self.size[y_root]:
106+
x_root, y_root = y_root, x_root
107+
self.uf[y_root] = x_root
108+
self.size[x_root] += self.size[y_root]
109+
self.size[y_root] = 0
110+
self.count -= 1
111+
112+
def connected(self, x, y): # 判断两个节点是否联通
113+
return self.find(x) == self.find(y)
114+
115+
class Solution:
116+
def swimInWater(self, grid):
117+
"""
118+
:type grid: List[List[int]]
119+
:rtype: int
120+
"""
121+
N = len(grid)
122+
location = {grid[i][j]: (i, j) for i in range(N) for j in range(N)}
123+
uf = UnionFind(N**2)
124+
125+
for time in range(N**2):
126+
i, j = location[time]
127+
for x, y in [(1, 0), (-1, 0), (0, 1), (0, -1)]:
128+
new_i, new_j = i + x, j + y
129+
if 0 <= new_i < N and 0 <= new_j < N and grid[new_i][new_j] <= time:
130+
uf.union(i * N + j, new_i * N + new_j)
131+
if uf.connected(0, N**2-1):
132+
return time
133+
```
134+
135+
136+
137+
> 思路 3
138+
******- 时间复杂度: O(N^2lgN)******- 空间复杂度: O(N^2)******
139+
140+
二分 + DFS
141+
142+
最多时间为N^2-1, 最少为0,我先看看mid能不能到,不能就继续二分,每一次看能不能到都是一个新的dfs(即全新的空的visited)
143+
144+
beats 27.78%
145+
146+
```python
147+
class Solution:
148+
def swimInWater(self, grid):
149+
"""
150+
:type grid: List[List[int]]
151+
:rtype: int
152+
"""
153+
self.N = len(grid)
154+
# self.visited = {}
155+
left, right = grid[0][0], self.N * self.N - 1
156+
while left < right:
157+
mid = left + (right - left) // 2
158+
if self.canReach(grid, mid, 0, 0, {}):
159+
right = mid
160+
else:
161+
left = mid + 1
162+
return left
163+
164+
def canReach(self, grid, time, i, j, visited):
165+
visited[(i,j)] = 1
166+
for x, y in [(1, 0), (-1, 0), (0, 1), (0, -1)]:
167+
new_i, new_j = i + x, j + y
168+
if 0 <= new_i < self.N and 0 <= new_j < self.N and \
169+
(new_i, new_j) not in visited and grid[new_i][new_j] <= time:
170+
if new_i == new_j == self.N - 1:
171+
return True
172+
if self.canReach(grid, time, new_i, new_j, visited):
173+
return True
174+
return False
175+
```
176+
177+
178+
179+
180+
181+
182+
183+
184+
185+
186+
187+
188+
189+
190+
191+
192+
193+
194+
195+
196+
197+
198+
199+
200+
78201

79202

80203

0 commit comments

Comments
 (0)