接雨水、二维接雨水

接雨水

问题描述

LeetCode链接:接雨水

思路

双指针,分别定义左边和右边最大值,那边最大值小,先结算哪边。

class TrappingRainWater:
    """
    接雨水,一维
    https://leetcode.cn/problems/trapping-rain-water/
    """
    def solution(self, height: List[int]) -> int:
        if not height or len(height) < 3:
            return 0

        n = len(height)
        l, r = 1, n-2
        left_max, right_max = height[0], height[n-1]
        res = 0

        while l <= r:
            if left_max >= right_max:
                res += max(0, right_max-height[r])
                right_max = max(right_max, height[r])
                r -= 1
            else:
                res += max(0, left_max-height[l])
                left_max = max(left_max, height[l])
                l += 1
        return res


二维接雨水

实现

class TrappingRainWater2:
    """
    接雨水,二维
    """
    class Node:
        def __init__(self, value, row, col):
            self.value = value
            self.row = row
            self.col = col

        def __lt__(self, other):
            """
            自定义比较器
            :param other:
            :return:
            """
            if self.value <= other.value:
                return True
            else:
                return False

    def solution(self, height: List[List[int]]) -> int:
        if not height:
            return 0
        n = len(height)
        m = len(height[0])
        isEnter = [[False] * m for _ in range(n)]

        # 定义小根堆
        hp = []
        # 第一行
        for col in range(m-1):
            val = height[0][col]
            new_node = TrappingRainWater2.Node(val, 0, col)
            heapq.heappush(hp, new_node)
            isEnter[0][col] = True
            
		# 最后一列
        for row in range(n-1):
            val = height[row][m-1]
            new_node = TrappingRainWater2.Node(val, row, m-1)
            heapq.heappush(hp, new_node)
            isEnter[row][m-1] = True
		
		# 最后一行
        for col in range(m-1, 0, -1):
            val = height[n-1][col]
            new_node = TrappingRainWater2.Node(val, n-1, col)
            heapq.heappush(hp, new_node)
            isEnter[n-1][col] = True
            
		# 第一列
        for row in range(n-1, 0, -1):
            val = height[row][0]
            new_node = TrappingRainWater2.Node(val, row, 0)
            heapq.heappush(hp, new_node)
            isEnter[row][0] = True

        cur_max = 0
        res = 0
        while hp:
            cur_node = heapq.heappop(hp)
            cur_max = max(cur_max, cur_node.value)
            r, c = cur_node.row, cur_node.col
            # 上方格子  雨水结算
            if r > 0 and not isEnter[r-1][c]:
                res += max(0, cur_max-height[r-1][c])
                isEnter[r-1][c] = True
                val = height[r-1][c]
                new_node = TrappingRainWater2.Node(val, r-1, c)
                heapq.heappush(hp, new_node)

            # 下方格子 雨水结算
            if r < n-1 and not isEnter[r + 1][c]:
                res += max(0, cur_max - height[r + 1][c])
                isEnter[r + 1][c] = True
                val = height[r + 1][c]
                new_node = TrappingRainWater2.Node(val, r + 1, c)
                heapq.heappush(hp, new_node)

            # 左方格子 雨水结算
            if c > 0 and not isEnter[r][c-1]:
                res += max(0, cur_max - height[r][c-1])
                isEnter[r][c-1] = True
                val = height[r][c-1]
                new_node = TrappingRainWater2.Node(val, r, c-1)
                heapq.heappush(hp, new_node)

            # 右方格子 雨水结算
            if c < m - 1 and not isEnter[r][c+1]:
                res += max(0, cur_max - height[r][c+1])
                isEnter[r][c+1]= True
                val = height[r][c+1]
                new_node = TrappingRainWater2.Node(val, r, c + 1)
                heapq.heappush(hp, new_node)
                
        return res
        

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

NLP_wendi

谢谢您的支持。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值