该题解使用了最小堆来解决接雨水问题。首先将矩阵周边的元素加入最小堆,并初始化水位数组water。然后不断从堆顶取出高度最小的元素,判断其四周是否有未访问过的元素,如果有就计算该位置能接的雨水量,并将其加入最小堆。重复这个过程直到堆为空,最终的接雨水总量就是答案。
时间复杂度: O(mn * log(mn))
空间复杂度: O(mn)
class Solution:
def trapRainWater(self, heightMap: List[List[int]]) -> int:
m,n = len(heightMap),len(heightMap[0])
min_height = []
water = [[-1 for j in range(n)] for i in range(m)] # 初始化water数组,-1表示未访问过
# 将矩阵上下边界加入最小堆
for j in range(n):
heapq.heappush(min_height,(heightMap[0][j],0,j))
water[0][j] = heightMap[0][j]
heapq.heappush(min_height,(heightMap[m-1][j],m-1,j))
water[m-1][j] = heightMap[m-1][j]
# 将矩阵左右边界加入最小堆
for i in range(1,m-1):
heapq.heappush(min_height,(heightMap[i][0],i,0))
water[i][0] = heightMap[i][0]
heapq.heappush(min_height,(heightMap[i][n-1],i,n-1))
water[i][n-1] = heightMap[i][n-1]
self.ans = 0
# 计算位置(i,j)能接的雨水量
def cal_water(h,i,j):
if heightMap[i][j] >= h:
water[i][j] = heightMap[i][j]
else:
self.ans += h - heightMap[i][j] # 累加接雨水量
water[i][j] = h
heapq.heappush(min_height, (water[i][j],i,j))
while min_height:
h, i, j = heapq.heappop(min_height) # 取出堆顶元素
# 判断四周是否有未访问过的元素
if i > 0 and water[i-1][j] == -1:
cal_water(h,i-1,j)
if i < m-1 and water[i+1][j] == -1:
cal_water(h,i+1,j)
if j > 0 and water[i][j-1] == -1:
cal_water(h,i,j-1)
if j < n-1 and water[i][j+1] == -1:
cal_water(h,i,j+1)
return self.ans