[
union find
dfs
bfs
binary search
]
Leetcode 1970. Last Day Where You Can Still Cross
Problem statement
https://leetcode.com/problems/last-day-where-you-can-still-cross/
Solution
When you see that problem is about connectivity of some parts of graph, you should immedietly think about Union Find. In fact this problem is very similar to problem 0803. Bricks Falling When Hit, let us go through algorithm.
- First of all, we are asked to find the moment of time when graph stop to be connected, so we remove connections one by one and union find allows us to do the opposite: add connections. So, what we need to do is to start from the end: we add all water cells to our
gridand then create all connections: between pairs of adjacent0. Also we need to create dummy variables for element which connected with top row and another element which connected with bottom row. So, our dsu structure will havemn + 2elements in total. update Actually it is given in problem description thatlen(C) = m*n, so in the end we will have all elements being water. - After we created all connections for the last position, we start form the last element in
Cand replace water with land: we makegrid[x][y] = 0and then create all connections. If we see that cell0is connected with cellmn + 1, it means that we have path from the top to bottom.
Complexity
It is O(mn + C*alpha(mn)), where alpha is inverse Ackermann function. Given that it grows very slow we can say that it is just O(mn). Space complexity is O(mn) as well.
Code
class DSU:
def __init__(self, N):
self.p = list(range(N))
def find(self, x):
if self.p[x] != x:
self.p[x] = self.find(self.p[x])
return self.p[x]
def union(self, x, y):
xr = self.find(x)
yr = self.find(y)
self.p[xr] = yr
class Solution:
def latestDayToCross(self, n, m, C):
row, col = len(C), len(C[0])
dsu = DSU(m*n + 2)
grid = [[1] * m for _ in range(n)]
neibs = [[0,1],[0,-1],[1,0],[-1,0]]
C = [(x-1, y-1) for x, y in C]
def index(x, y):
return x * m + y + 1
for i in range(len(C) - 1, -1, -1):
x, y = C[i][0], C[i][1]
grid[x][y] = 0
for dx, dy in neibs:
ind = index(x+dx, y+dy)
if x+dx>=0 and x+dx<n and y + dy >= 0 and y + dy < m and grid[x+dx][y+dy] == 0:
dsu.union(ind, index(x, y))
if x == 0:
dsu.union(0, index(x, y))
if x == n - 1:
dsu.union(m*n + 1, index(x, y))
if dsu.find(0) == dsu.find(m*n + 1):
return i
Remark
I just realized that it is possible to solve this problem with binary search as well: we need to find the moment of time when graph becomes unconnected, complexity will be O(mn*log(C)).