zoukankan      html  css  js  c++  java
  • 边工作边刷题:70天一遍leetcode: day 92

    Shortest Distance from All Buildings

    要点:

    • 这种没有weight的distance题,首先想到dfs/bfs。这题因为是最短距离,所以用bfs。注意不同于Surrounded Regions,这题不是连通渲染,而是对每个’1’值点作为起点单独的bfs,而不是并行的起始点同时进queue初始化
    • 如何记录结果?bfs过程中,level是累加到某个点上的。但是并不知道是不是所有building都能到达,所以用reach来记录每个0点到达的1点(buildings)个数,最后统计的时候不考虑不能reach所有building的
    • 一个强力优化:bfs同时记录某个buildings连通的其他building个数,结束时如果不为所有building数,可以直接返回-1

    细节:

    • bfs,visited在开始的时候allocate
    • 数据结构:self.reach, self.dist, visited, count
    • return True/False直接依赖一个条件的时候直接返回条件,而不要if/else检查

    错误点:

    • 注意bfs的起始点是每个building,统计reach和sumLen的点是经过的0,count是对连通的1。最后结果是对所有0点
    • TypeError: 'int' object is not iterable: deque+pair的初始化极易错:错误:deque((x,y)),正确:deque([(x,y)])
    • next从deque变成list了:最后还是用单一object计数的方法
    • list comprehension中的variable不是list中local的
    • d+=1的位置:每层之外,初始为0
    • [[-1]]的corner case:如果bfs中初始count=0,不先set初始点的visited,这样初始点之后不能访问到,可以返回-1

    https://repl.it/Cc62/4

    from collections import deque
    
    class Solution(object):
        def shortestDistance(self, grid):
            """
            :type grid: List[List[int]]
            :rtype: int
            """
            def bfs(grid, m, n, x, y, total):
                visited = [[False]*n for _ in xrange(m)] # error: don't use x,y
                q = deque([(x,y)]) # error 1
                count=0
                # visited[x][y]=True
                dirs = [(1,0),(0,1),(-1,0),(0,-1)]
                d = 0
                while q:
                    # print q
                    ql = len(q) # error 2: use single object
                    d+=1
                    for _ in xrange(ql):
                        x,y = q.popleft()
                        for xd,yd in dirs:
                            x0,y0 = x+xd,y+yd
                            if 0<=x0<m and 0<=y0<n and not visited[x0][y0]:
                                visited[x0][y0]=True # error 3: dont forget
                                if grid[x0][y0]==0:
                                    self.dist[x0][y0]+=d
                                    self.reach[x0][y0]+=1
                                    q.append((x0,y0))
                                if grid[x0][y0]==1:
                                    # print x0,y0
                                    count+=1
                #print count, total
                return count==total
            
            m,n=len(grid),len(grid[0])
            total = sum([val for line in grid for val in line if val==1])
            self.dist = [[0 for y in xrange(n)] for x in xrange(m)]
            self.reach = [[0 for y in xrange(n)] for x in xrange(m)]
            for x in xrange(m):
                for y in xrange(n):
                    if grid[x][y]==1:
                        if not bfs(grid, m, n, x, y, total):
                            return -1
            
            shortest = sys.maxint
            for x in xrange(m):
                for y in xrange(n):
                    if self.reach[x][y]==total:
                       shortest = min(self.dist[x][y], shortest)
            
            return shortest
    
  • 相关阅读:
    MongoDB 释放磁盘空间 db.runCommand({repairDatabase: 1 })
    RK 调试笔记
    RK Android7.1 拨号
    RK Android7.1 移植gt9271 TP偏移
    RK Android7.1 定制化 itvbox 盒子Launcher
    RK Android7.1 双屏显示旋转方向
    RK Android7.1 设置 内存条作假
    RK Android7.1 设置 蓝牙 已断开连接
    RK Android7.1 进入Camera2 亮度会增加
    RK 3128 调触摸屏 TP GT9XX
  • 原文地址:https://www.cnblogs.com/absolute/p/5815833.html
Copyright © 2011-2022 走看看