大厂算法笔试题:3D接雨水

大厂面试会经常面试一些比较有难度的算法题目,我偶尔看到了这一个3D接雨水的题目,觉得很有意思,就自己尝试了一下,花了30分钟搞定。

下面分享我自己的算法,跟原算法比肯定简陋了些,但逻辑上是ok的。算抛砖引玉吧。

"""

算法题目链接
https://mp.weixin.qq.com/s/wYzUf4cx301etfPi7FrEwg
输入: heightMap = [[1,4,3,1,3,2],[3,2,1,3,2,4],[2,3,3,2,3,1]]
输出: 4
解释: 下雨后,雨水将会被上图蓝色的方块中。总的接雨水量为1+2+1=4。

输入: heightMap = [[3,3,3,3,3],[3,2,2,2,3],[3,2,1,2,3],[3,2,2,2,3],[3,3,3,3,3]]
输出: 10

下面是原题的解法:
def trapRainWater(self, heightMap: List[List[int]]) -> int:
    pq = []
    m = len(heightMap)  # 矩阵的高
    n = len(heightMap[0])  # 矩阵的宽
    visited = [[False for _ in range(n)] for _ in range(m)]

    # 先把四周所有元素添加到堆中。
    for i in range(m):
        for j in range(n):
            if i == 0 or i == m - 1 or j == 0 or j == n - 1:
                heapq.heappush(pq, (heightMap[i][j], i, j))
                visited[i][j] = True

    water = 0  # 接的雨水量
    # 上下左右
    dirs = [[0, -1], [0, 1], [-1, 0], [1, 0]]
    while pq:
        n0, n1, n2 = heapq.heappop(pq)
        for dx, dy in dirs:  # 遍历当前出队元素的上下左右四个方向。
            x = n1 + dx
            y = n2 + dy
            # 不能越界
            if x < 0 or x >= m or y < 0 or y >= n or visited[x][y]:
                continue
            visited[x][y] = True  # 标记为已计算过
            water += max(0, n0 - heightMap[x][y])  # 计算水量
            heapq.heappush(pq, (max(n0, heightMap[x][y]), x, y))
    return water

我这里提供了一个我个人的算法
"""


height_map = [[1,4,3,1,3,2],[3,2,1,3,2,4],[2,3,3,2,3,1]]

height_map2 = [[3,3,3,3,3],[3,2,2,2,3],[3,2,1,2,3],[3,2,2,2,3],[3,3,3,3,3]]

def trapRainWater(h_map):
    """
    :type h_map: List[List[int]]
    :rtype: int
    """
    if not h_map:
        return 0

    m, n = len(h_map), len(h_map[0])
    # print(m,n)
    rain=0

    for i in range(1,m-1):
        for j in range(1,n-1):
            print("h[%d][%d]=%d"%(i,j,h_map[i][j]))
            # 先定义东南西北四个方向的边界最大值
            max_s = h_map[0][j]
            max_n = h_map[m-1][j]
            max_e = h_map[i][0]
            max_w = h_map[i][n-1]
            print("for i=",i,"j=",j,"max_s=",max_s,"max_n=",max_n,"max_e=",max_e,"max_w=",max_w)
            # 然后按照东南西北四个方向对某个元素对应的四个边界最大值进行判断,如果大于该最大值,则取新的最大值
            for k in range(0,i):
                if h_map[k][j]>max_s:
                    max_s=h_map[k][j]
            for k in range(i,m-1):
                if h_map[k][j]>max_n:
                    max_n=h_map[k][j]
            for k in range(0,j):
                if h_map[i][k]>max_e:
                    max_e=h_map[i][k]
            for k in range(j,n-1):
                if h_map[i][k]>max_w:
                    max_w=h_map[i][k]
            # 然后将东南西北四个方向的最大值再取最小值与这个元素的值相减,就是存储的雨水量,但要注意的是,如果该值小于0,说明不会储水,则取0
            rain += max(min(max_s,max_n,max_e,max_w)-h_map[i][j],0)
            print("for i=", i, "j=", j, "max_s=", max_s, "max_n=", max_n, "max_e=", max_e, "max_w=", max_w)
            print(rain)
            return rain

trapRainWater(height_map)
trapRainWater(height_map2)

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值