接雨水2 python3实现

题目描述

给出 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
在这里插入图片描述

  • 思路一
    大纲:找二维数组的最小值,判断四周是否大于它,如果大,则将四周的最小值赋值给二维数组的最小值,并记录差值,循环往复,累加差值。
  1. 找到海拔最低点D(二维数组最小值)的下标加入列表xb,及D前后左右方位的值放在列表q中。
  2. 比较最低点D与q中最小值的大小,如果q的最小值等于D,则将q的最小值点作为新的D点,重复1,2步骤。
  3. 如果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

  • 思路二
    一圈一圈往里找,里面有比外墙高的地方,就缩小外墙范围,然后填充内部低洼部分得出结果。
  • 思路三
    将二维数组简化为一维的行和列去考虑问题。
发布了14 篇原创文章 · 获赞 8 · 访问量 671

猜你喜欢

转载自blog.csdn.net/weixin_44133727/article/details/99956305