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
以上