lc 778. Swim in Rising Water

note that : python support syntex like:
 if 0 <= i < N :
cool!


  the code below is in a djikstra way. every time you choose the shortest node to add to current known set, the only difference is the distance is
not in a adding way but max(a,b).
  apparently this method don't use the condition:grid[i][j] is range(0,n**2)
so a quick solution use this range by a binary search: if the water depth is h,will the two target reachable? which becomes a bfs problem.
  when a unsolved node is adjacent to an solved one and it's height is higher than the neighbor's dis, we are sure it's dis is it's height, so we
can expand this one without comparison.when we can't expand like this, we have to choose the smallest node ,and go on until grid[n-1][n-1] is solved.
solution1:
very clever,
seen=set() to store visited ones,so it only add while no pop
while headq to store the neighbors!!!!! we need to find the smallest one in a dynamic way so don't do in comparison ,instead use a headqueue.
very quick!!!
the question is why only use the height of the node while no neighbor info?
cause i pre-think in a dp way. However you don't need a node's shortest dis.
you only should add shortest neighbor a time and maintain a highest height.

in fact you even can simulate the water action, it will be fast than the dp way.
this is only from start point and use a set() to store visted nodes.
you can change to start at two points and use a grid[][] as visited flag.
    def swimInWater(self, grid):
        N, pq, seen, res = len(grid), [(grid[0][0], 0, 0)], set([(0, 0)]), 0
        while True:
            T, x, y = heapq.heappop(pq)
            res = max(res, T)
            if x == y == N - 1:
                return res
            for i, j in [(x + 1, y), (x, y + 1), (x - 1, y), (x, y - 1)]:
                if 0 <= i < N and 0 <= j < N and (i, j) not in seen:
                    seen.add((i, j))
                    heapq.heappush(pq, (grid[i][j], i, j))
View Code

solution2:
binary search and check reachable:


solution3
: too time consuming!!!

class
Solution: def __init__(self): self.dp=None self.g=None # self.maxint=9223372036854775807 def valid(self,i,j): a=[] for x,y in [(-1,0),(1,0),(0,1),(0,-1)]: x+=i y+=j if x>=0 and x<len(self.g) and y>=0 and y<len(self.g): a.append((x,y)) return a def nei_dis(self,i,j): a=-1 for x,y in self.valid(i,j): if self.dp[x][y]!=-1: if a==-1: a=self.dp[x][y] else: a=min(a,self.dp[x][y]) return a def settle(self,i,j,d): self.dp[i][j]=d a=[] for x,y in self.valid(i,j): if self.dp[x][y]==-1 and self.g[x][y]>self.dp[i][j]: a.append((x,y,self.g[x][y])) return a def swimInWater(self, grid): """ :type grid: List[List[int]] :rtype: int """ n=len(grid) self.g=grid self.dp=[[-1]*n for i in range(n)] self.dp[0][0]=grid[0][0] tosettle=[(0,0,grid[0][0])] while self.dp[n-1][n-1]==-1: next=[] mindis=-1 minx=-1 miny=-1 if len(tosettle)==0: for i in range(n): for j in range(n): if self.dp[i][j]!=-1: continue nd=self.nei_dis(i,j) if nd==-1: continue nd=max(self.g[i][j],nd) if mindis==-1 or nd<mindis: mindis=nd minx=i miny=j tosettle.append((minx,miny,mindis)) for x,y,d in tosettle: next+=self.settle(x,y,d) tosettle=next return self.dp[n-1][n-1]


 

posted @ 2018-09-07 17:34  Cloud.9  阅读(181)  评论(0编辑  收藏  举报