leetcode 打卡 day59

● 503.下一个更大元素II ● 42. 接雨水

503.下一个更大元素II

在遍历的过程中模拟走了两边nums。

class Solution:
    def nextGreaterElements(self, nums: List[int]) -> List[int]:
        result = [-1] * len(nums)
        stack = []
        for i in range(2*len(nums)):
            while(len(stack) != 0 and nums[i%len(nums)] > nums[stack[-1]]):
                result[stack[-1]] = nums[i % len(nums)]
                stack.pop()
            stack.append(i%len(nums))
        return result

42. 接雨水

双指针,会超时

class Solution:
    def trap(self, height: List[int]) -> int:
        # 双指针
        res = 0
        for i in range(len(height)):
            if i == 0 or i == len(height)-1: continue
            lHight = height[i-1]
            rHight = height[i+1]
            for j in range(i-1):
                if height[j] > lHight:
                    lHight = height[j]
            for k in range(i+2,len(height)):
                if height[k] > rHight:
                    rHight = height[k]
            res1 = min(lHight,rHight) - height[i]        
            if res1 > 0:
                res += res1
        return res

动态规划

class Solution:
    def trap(self, height: List[int]) -> int:
        # 动态规划
        left_height = [0] * len(height)
        right_height = [0] * len(height)
        left_height[0] = height[0]
        # 记录每个柱子左边柱子最大高度
        for i in range(1, len(height)):
            left_height[i] = max(left_height[i-1], height[i])
        right_height[-1] = height[-1]
        # 记录每个柱子右边柱子最大高度
        for j in range(len(height)-2, -1, -1):
            right_height[j] = max(right_height[j+1], height[j])
        result = 0
        for k in range(len(height)):
            sum_val = min(left_height[k], right_height[k])-height[k]
            result += sum_val
        return result

单调栈

class Solution:
    def trap(self, height: List[int]) -> int:
        # 单调栈
         # 单调栈
        '''
        单调栈是按照 行 的方向来计算雨水
        从栈顶到栈底的顺序:从小到大
        通过三个元素来接水:栈顶,栈顶的下一个元素,以及即将入栈的元素
        雨水高度是 min(凹槽左边高度, 凹槽右边高度) - 凹槽底部高度
        雨水的宽度是 凹槽右边的下标 - 凹槽左边的下标 - 1(因为只求中间宽度)
        '''
        # stack储存index,用于计算对应的柱子高度
        stack = [0]
        result = 0
        for i in range(1, len(height)):
        	# 情况一
            if height[i] < height[stack[-1]]:
                stack.append(i)
            #  情况二
            # 当前柱子高度和栈顶一致时,左边的一个是不可能存放雨水的,所以保留右侧新柱子
            # 需要使用最右边的柱子来计算宽度
            elif height[i] == height[stack[-1]]:
                stack.pop()
                stack.append(i)
            # 情况三
            else:
                # 抛出所有较低的柱子
                while stack and height[i] > height[stack[-1]]:
                    # 栈顶就是中间的柱子:储水槽,就是凹槽的地步
                    mid_height = height[stack[-1]]
                    stack.pop()
                    if stack:
                        right_height = height[i]
                        left_height = height[stack[-1]]
                        # 两侧的较矮一方的高度 - 凹槽底部高度
                        h = min(right_height, left_height) - mid_height
                        # 凹槽右侧下标 - 凹槽左侧下标 - 1: 只求中间宽度
                        w = i - stack[-1] -1
                         # 体积:高乘宽
                        result += h*w
                stack.append(i)
        return result
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值