leetcode 407 接雨水

三维空间的接雨水
有一点像dijkstar最短路径搜索。
所谓dijkstar, 是有一个closeset的,closeset表明的是已经确定距离的位置。
初始位置是closeset,每次都取与closeset相邻的最近的点放入到closet中。 相邻的点用一个最小堆来维护。

这道题也是一样, 初始的closeset是周围一圈,因为周围一圈是不会存雨水的。 然后取其中最小的值,该点为a点, 与最小的值相邻的某个点b的雨水高度可以由a,b中的高度最大值获得, 此时b点的接完雨水的高度也已经确定, 可以放入的close队列中去。

以上

class Solution:
    def trapRainWater(self, heightMap: List[List[int]]) -> int:
        if not heightMap or not heightMap[0]:
            return 0
        line_num = len(heightMap)
        col_num = len(heightMap[0])
        if line_num <= 2 or col_num <=2:
            return 0
        result = 0
        open_sign_list = [[0 for _ in range(col_num)] for _ in range(line_num)]

        height_list = []
        for j in range(col_num):
            heapq.heappush(height_list, (heightMap[0][j], 0, j))
            heapq.heappush(height_list, (heightMap[line_num - 1][j], line_num - 1, j))
            open_sign_list[0][j] = 1
            open_sign_list[line_num - 1][j] = 1

        for i in range(1, line_num - 1):
            heapq.heappush(height_list, (heightMap[i][0], i, 0))
            heapq.heappush(height_list, (heightMap[i][col_num - 1], i, col_num - 1))
            open_sign_list[i][0] = 1
            open_sign_list[i][col_num - 1] = 1

        while height_list:
            height, i, j = heapq.heappop(height_list)
            for x, y in [(i - 1, j), (i + 1, j), (i, j -1), (i, j + 1)]:
                if x > line_num - 1 or x < 0 or y > col_num - 1 or y < 0:
                    continue
                elif open_sign_list[x][y] == 1:
                    continue
                else:
                    current_height = heightMap[x][y]
                    final_height = max(current_height, height)
                    heapq.heappush(height_list, (final_height, x, y))
                    result += final_height - current_height
                    open_sign_list[x][y] = 1

        return result

上述的方法在遇到相邻的点依旧是最低点的时候会入堆出堆一次, 所以简单再优化一下

class Solution:
    def trapRainWater(self, heightMap: List[List[int]]) -> int:
        if not heightMap or not heightMap[0]:
            return 0
        line_num = len(heightMap)
        col_num = len(heightMap[0])
        if line_num <= 2 or col_num <=2:
            return 0
        result = 0
        open_sign_list = [[0 for _ in range(col_num)] for _ in range(line_num)]

        height_list = []
        for j in range(col_num):
            heapq.heappush(height_list, (heightMap[0][j], 0, j))
            heapq.heappush(height_list, (heightMap[line_num - 1][j], line_num - 1, j))
            open_sign_list[0][j] = 1
            open_sign_list[line_num - 1][j] = 1

        for i in range(1, line_num - 1):
            heapq.heappush(height_list, (heightMap[i][0], i, 0))
            heapq.heappush(height_list, (heightMap[i][col_num - 1], i, col_num - 1))
            open_sign_list[i][0] = 1
            open_sign_list[i][col_num - 1] = 1

        # 我这里的思路就是如果相邻的点依旧是最小点就无需入堆再出堆了
        tmp_list = []
        while tmp_list or height_list:
            if tmp_list:
                height, i, j = tmp_list.pop()
            else:
                height, i, j = heapq.heappop(height_list)

            for x, y in [(i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)]:
                if x > line_num - 1 or x < 0 or y > col_num - 1 or y < 0:
                    continue
                elif open_sign_list[x][y] == 1:
                    continue
                else:
                    current_height = heightMap[x][y]
                    if current_height > height:
                        final_height = current_height
                        heapq.heappush(height_list, (final_height, x, y))
                        open_sign_list[x][y] = 1
                    else:
                        open_sign_list[x][y] = 1
                        tmp_list.append((height, x, y))
                        result += height - current_height
        return result

以上

posted @ 2022-03-28 00:28  茫茫碧落  阅读(128)  评论(0编辑  收藏  举报