LeetCode 42 接雨水

题目描述

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。

法一:动态规划

主要思想: 提前储存所有左边位置的最大值和右边位置的最大值

  • 时间复杂度:O(n)
  • 空间复杂度:O(n)
def trap(self, height: List[int]) -> int:
    # 初始化
    ans = 0
    left_max = [0] * len(height) # dp数组
    right_max = [0] * len(height) # dp数组

    # 状态转移
    # update left_max      
    for i in range(len(height)):
        if i == 0: # 第一个元素
            left_max[i] = height[i]
        else:
            left_max[i] = max(left_max[i-1], height[i])

    # update right_max
    for j in range(len(height)-1, -1, -1):
        if j == len(height)-1: # 最后一个元素
            right_max[j] = height[j]
        else:
            right_max[j] = max(right_max[j+1], height[j])

    # update ans
    for i in range(len(height)):
        ans+= min(left_max[i],right_max[i]) -  height[i]
    
    return ans

法二:单调栈

主要思想: 积水只能在低洼处形成,当后面的柱子高度比前面的低,是无法接雨水的。所以用单调栈储存可能储存的柱子,当找到一根比前面高的柱子,就可以接到雨水。

  • 时间复杂度:O(n)
  • 空间复杂度:O(n)
def trap(self, height: List[int]) -> int:
    from collections import deque
    ans = 0 
    st = deque(maxlen=len(height)) # 使用collections.deque实现栈

    right_idx = 0 # 记录索引
    while right_idx < len(height):

        while st and height[st[-1]]<height[right_idx]: 
            curr_idx = st.pop() 
            if not st: # 判断是否已空
                break
            intv =  right_idx - st[-1] - 1
            height_diff = min(height[st[-1]], height[right_idx]) - height[curr_idx]
            ans += intv * height_diff # 增量累计

        # 更新索引
        st.append(right_idx) 
        right_idx+=1

   return ans

法三:双指针

  • 时间复杂度:O(n)
  • 空间复杂度:O(1)
def trap(self, height: List[int]) -> int:
    # 初始化
    ans = 0
    left, right = 0, len(height) - 1
    left_max, right_max = 0, 0

    # 移动左右指针
    while left < right:
        # 分成两端
        if height[left] < height[right]: 
            if left_max < height[left]:
                left_max = height[left]
            else:
                ans += left_max - height[left]
            left+=1
        else:
            if right_max < height[right]:
                right_max = height[right]
            else:
                ans += right_max - height[right]
            right-=1
    
    return ans

参考资料

  1. 力扣官方题解:接雨水
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值