LeetCode 接雨水

LeetCode 练习题26

接雨水

题目描述

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

上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。 感谢 Marcos 贡献此图。

示例:

输入: [0,1,0,2,1,0,1,3,2,1,2,1]
输出: 6

在这里插入图片描述

解题方法

class Solution:
    def trap(self, height: List[int]) -> int:
        
        """
        暴力法
        结果:  超出时长
        res , left_max, right_max = 0, -1, -1
        for i, h in enumerate(height):
            left_max = max(height[:i]) if len(height[:i])>0 else -1
            right_max = max(height[i:]) if len(height[i+1:])>0 else height[-1]
            if min(left_max, right_max)>h: res += min(left_max, right_max)-h           
        return res
        """
        
        """
        存储左边最大值,减小每次计算max(left_height)的时间
        res , left_max, right_max = 0, -1, -1
        for i, h in enumerate(height):
            if h>left_max: left_max = h
            right_max = max(height[i:]) if len(height[i+1:])>0 else height[-1]
            res += min(left_max, right_max)-h           
        return res
        """   
        
        """
        存储每个元素对应的左边及右边最大值, 减小计算最大值是的计算量
        res , left_maxs, right_maxs = 0, [-1], [-1]
        for h in height[:-1]:
            if h>left_maxs[-1]: left_maxs.append(h)
            else: left_maxs.append(left_maxs[-1])
        for i in range(len(height)-1, 0, -1):
            if height[i]>right_maxs[-1]: right_maxs.append(height[i])
            else: right_maxs.append(right_maxs[-1])
        right_maxs.reverse()
        #print(left_maxs, right_maxs)
        for i, h in enumerate(height):
            if min(left_maxs[i], right_maxs[i])>h: res += min(left_maxs[i], right_maxs[i])-h           
        return res
        """
        
        """
        利用双指针,对左右left_max,right_max进行存储
        if not height: return 0
        left_max, right_max = height[0], height[-1]
        left, right, res = 0, len(height)-1, 0
        
        while(left<=right):
            if left_max<=right_max:
                if height[left]>=left_max: left_max= height[left]
                else: res= res+left_max-height[left]
                #print(left, res)
                left+=1
            else: 
                if height[right]>=right_max: right_max = height[right]
                else: res += right_max - height[right]
                #print(right, res)
                right-=1
        return res
        """
        
        if not height: return 0
        n = len(height)
        stack = []
        res = 0
        for i in range(n):
            #print(stack, res)
            while stack and height[stack[-1]] < height[i]:
                tmp = stack.pop()
                if not stack: break
                res += (min(height[i], height[stack[-1]]) - height[tmp]) * (i-stack[-1] - 1)
            stack.append(i)
        return res
        
       

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值