题目描述
给出 n * m 个非负整数,代表一张X轴上每个区域为 1 * 1 的 2d 海拔图, 计算这个海拔图最多能接住多少(面积)雨水。
例如,给定一个 5*4 的矩阵:
输入: [[12,13,0,12],[13,4,13,12],[13,8,10,12],[12,13,12,12],[13,13,13,13]]
输出: 14
原题链接https://leetcode-cn.com/problems/trapping-rain-water-ii/
https://www.lintcode.com/problem/trapping-rain-water-ii/description
- 思路一
大纲:找二维数组的最小值,判断四周是否大于它,如果大,则将四周的最小值赋值给二维数组的最小值,并记录差值,循环往复,累加差值。
- 找到海拔最低点D(二维数组最小值)的下标加入列表xb,及D前后左右方位的值放在列表q中。
- 比较最低点D与q中最小值的大小,如果q的最小值等于D,则将q的最小值点作为新的D点,重复1,2步骤。
- 如果q的最小值大于D,则将q的最小值赋值给D,如果xb中的点不在数组的最外层,则所求结果应累加 列表xb的长度 *(q的最小值 - D),重复上述步骤直到D等于二维数组的最大值结束。
看到这里可以试着自己写一写哦
class Solution(object):
# 返回最小值下标
def mind(self,yus):
a = [min(i) for i in yus]
a = a.index(min(a))
b = [i.index(min(i)) for i in yus][a]
return a,b
# 获得上下左右的数据
def lrud(self,yus,i,j,m,n,ma):
if i > 0:up = yus[i-1][j] #上
else:up = ma
if i < m-1:dn = yus[i+1][j] #下
else:dn = ma
if j > 0:l = yus[i][j-1] #左
else:l = ma
if j < n-1:r = yus[i][j+1] #右
else:r = ma
return up,dn,l,r
def xh(self,m,n,a,b,xb,qq,q,hhhh,yus,ma):
xb.append([a,b])
li = [i for i, x in enumerate(q) if x == yus[a][b]]
if min(q) == yus[a][b]:
for k in li:
if k/2 < 1:
t = [a-1,a+1,b-1,b+1][k]
if 0<=t<=m-1 and 0<=b<=n-1:
q = self.lrud(yus,t,b,m,n,ma)
qq = qq|set(q)
if t in [0,m-1] or b in [0,n-1]:
hhhh = 1
if [t,b] not in xb:
xb,qq,hhhh = self.xh(m,n,t,b,xb,qq,q,hhhh,yus,ma)
else:
y = [a-1,a+1,b-1,b+1][k]
if 0<=a<=m-1 and 0<=y<=n-1:
q = self.lrud(yus,a,y,m,n,ma)
qq = qq|set(q)
if a in [0,m-1] or y in [0,n-1]:
hhhh = 1
if [a,y] not in xb:
xb,qq,hhhh = self.xh(m,n,a,y,xb,qq,q,hhhh,yus,ma)
else:
if a in [0,m-1] or b in [0,n-1]:
hhhh = 1
return xb,qq,hhhh
def trapRainWater(self, yus):
"""
:type heightMap: List[List[int]]
:rtype: int
"""
if yus == []:
return 0
z = 0
xb = []
m,n = len(yus),len(yus[0])
ma = max([max(i) for i in yus])
while True:
a,b = self.mind(yus)
if yus[a][b] == ma:
break
q = self.lrud(yus,a,b,m,n,ma)
qq = set(q)
hhhh = 0
xb,qq,hhhh = self.xh(m,n,a,b,xb,qq,q,hhhh,yus,ma)
qq = list(qq)
qq.sort(reverse=True)
qp = qq.pop()
while True:
if qp == yus[a][b]:
qp = qq.pop()
else:
break
if hhhh == 0:
z = z + len(xb) * (qp-yus[a][b])
for aa,bb in xb:
yus[aa][bb] = qp
xb,hhhh = [],0
return z
- 思路二
一圈一圈往里找,里面有比外墙高的地方,就缩小外墙范围,然后填充内部低洼部分得出结果。 - 思路三
将二维数组简化为一维的行和列去考虑问题。