Use this to learn the idea, then write your own version.
123 45class UnionFind(object): 6 def __init__(self, n):7 self.set = range(n)8 self.rank = [0]*n9 self.right = range(n) 10 11 def find_set(self, x):12 stk = []13 while self.set[x] != x: 14 stk.append(x)15 x = self.set[x]16 while stk:17 self.set[stk.pop()] = x18 return x19 20 def union_set(self, x, y):21 x, y = self.find_set(x), self.find_set(y)22 if x == y:23 return False24 if self.rank[x] > self.rank[y]: 25 x, y = y, x26 self.set[x] = self.set[y]27 if self.rank[x] == self.rank[y]:28 self.rank[y] += 129 self.right[y] = max(self.right[x], self.right[y]) 30 return True31 32 def right_set(self, x): 33 return self.right[self.find_set(x)]34 35 36class Solution(object):37 def minimumVisitedCells(self, grid):38 """39 :type grid: List[List[int]]40 :rtype: int41 """42 m, n = len(grid), len(grid[0])43 uf1 = [UnionFind(n+1) for _ in xrange(m)]44 uf2 = [UnionFind(m+1) for _ in xrange(n)]45 d, i, j = 1, 0, 046 q = [(i, j)]47 uf1[i].union_set(j, j+1)48 uf2[j].union_set(i, i+1)49 while q:50 new_q = []51 for i, j in q:52 if (i, j) == (m-1, n-1):53 return d54 while uf1[i].right_set(j) <= min(j+grid[i][j], n-1):55 k = uf1[i].right_set(j)56 new_q.append((i, k))57 uf2[k].union_set(i, i+1)58 uf1[i].union_set(k, k+1)59 while uf2[j].right_set(i) <= min(i+grid[i][j], m-1):60 k = uf2[j].right_set(i)61 new_q.append((k, j))62 uf1[k].union_set(j, j+1)63 uf2[j].union_set(k, k+1)64 q = new_q65 d += 166 return -167 68 697071from sortedcontainers import SortedList72 73 7475class Solution2_TLE(object):76 def minimumVisitedCells(self, grid):77 """78 :type grid: List[List[int]]79 :rtype: int80 """81 m, n = len(grid), len(grid[0])82 sl1 = [SortedList(xrange(n)) for _ in xrange(m)]83 sl2 = [SortedList(xrange(m)) for _ in xrange(n)]84 d, i, j = 1, 0, 085 q = [(i, j)]86 while q:87 new_q = []88 for i, j in q:89 if (i, j) == (m-1, n-1):90 return d91 for k in list(sl1[i].irange(j+1, min(j+grid[i][j], n-1))):92 new_q.append((i, k))93 sl2[k].remove(i)94 sl1[i].remove(k)95 for k in list(sl2[j].irange(i+1, min(i+grid[i][j], m-1))):96 new_q.append((k, j))97 sl1[k].remove(j)98 sl2[j].remove(k)99 q = new_q100 d += 1101 return -1102