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

    Walls and Gates
    要点:

    • 同样是bfs,这题可以用渲染的方法(即全部gate进初始q),注意区别Shortest Distance from All Buildings。那道题要找到某个点到"all" buildings的距离,所以不能用渲染,因为不是到该点的一条路径。而本题类似surrounded region,最终的最佳路径只取一条路径
    • bfs的方法全是在展开后入q前更新
    • 剪枝:只要值更新了,就一定是最小值。不用入q了

    错误点:

    • 忘了更新距离。因为gate是0,所以距离可以统一更新为从哪来的+1

    https://repl.it/CfGu/1

    # You want to build a house on an empty land which reaches all buildings in the shortest amount of distance. You can only move up, down, left and right. You are given a 2D grid of values 0, 1 or 2, where:
    
    # Each 0 marks an empty land which you can pass by freely.
    # Each 1 marks a building which you cannot pass through.
    # Each 2 marks an obstacle which you cannot pass through.
    # For example, given three buildings at (0,0), (0,4), (2,2), and an obstacle at (0,2):
    
    # 1 - 0 - 2 - 0 - 1
    # |   |   |   |   |
    # 0 - 0 - 0 - 0 - 0
    # |   |   |   |   |
    # 0 - 0 - 1 - 0 - 0
    # The point (1,2) is an ideal empty land to build a house, as the total travel distance of 3+3+1=7 is minimal. So return 7.
    
    # Note:
    # There will be at least one building. If it is not possible to build such house according to the above rules, return -1.
    
    
    
    from collections import deque
    import sys
    
    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
                dirs = [(1,0),(0,1),(-1,0),(0,-1)]
                d = 0
                while 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:
                                    count+=1
                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
    
    sol = Solution() 
    assert sol.shortestDistance([[1,0,2,0,1],[0,0,0,0,0],[0,0,1,0,0]])==7, "must be 7"
    assert sol.shortestDistance([[1]])==-1, "must be -1"
    
    
  • 相关阅读:
    「ZJOI2019」开关
    「ZJOI2019」Minimax 搜索
    杨氏矩阵学习笔记
    「LibreOJ NOI Round #2」简单算术
    「LibreOJ NOI Round #2」小球进洞
    组合总和 II(力扣第40题)
    组合总和 I(力扣第39题)
    组合(力扣第77题)
    使用MapReduce解决蚂蚁森林第二题
    Hive练习--蚂蚁森林习题二
  • 原文地址:https://www.cnblogs.com/absolute/p/5815776.html
Copyright © 2011-2022 走看看