【代码随想录算法训练营】第59天 | 第十章 单调栈(二)+ 复习第31天 第七章 贪心(一)

主要内容

单调栈

单调栈题目

503. 下一个更大元素 II

代码

拼接,浪费空间,时间

class Solution:
    def nextGreaterElements(self, nums: List[int]) -> List[int]:
        n = len(nums)
        newnums = nums + nums
        stack = []
        res = [-1] * (2 * n)
        for i in range(2*n):
            # 弹出
            while stack and newnums[i] > newnums[stack[-1]]:
                index = stack.pop()
                res[index] = newnums[i]
            stack.append(i)
        return res[:n]    
class Solution:
    def nextGreaterElements(self, nums: List[int]) -> List[int]:
        n = len(nums)
        res = [-1] * n
        stack = []
        for i in range(2 * n):
            # 弹出,记录
            while stack and nums[i % n] > nums[stack[-1]]:
                index = stack.pop()
                res[index] = nums[i % n]
            # 加入
            stack.append(i % n)
        return res         

42. 接雨水

思路分析

在这里插入图片描述

  1. 双指针:超时了 (计算雨水高)
  2. 动态规划:优化计算左右最高 (计算雨水高)
  3. 单调栈:形成凹槽(计算雨水行)
    在这里插入图片描述

代码

class Solution:
    # 双指针方法,计算雨水高, 超时了
    # 对于当前高度,找到其左边最高的柱子lefth,右边最高的柱子righth,
    # 则当前柱子上的雨水高度为 min(lefth, righth) - height[i]
    def trap(self, height: List[int]) -> int:
        res = 0
        n = len(height)
        for i in range(1, n - 1):
            lefth = height[i-1]
            righth = height[i+1]
            # 向左找最高
            for j in range(i-1):
                lefth = max(lefth, height[j])
            # 向右找最高
            for j in range(i+2, n):
                righth = max(righth, height[j])
            h = min(lefth, righth) - height[i]
            if h > 0:
                res += h 
        return res     
class Solution:
    # 采用动态规划,优化左右最高柱子的计算
    # 对于当前高度,找到其左边最高的柱子lefth,右边最高的柱子righth,
    # 则当前柱子上的雨水高度为 min(lefth, righth) - height[i]
    def trap(self, height: List[int]) -> int:
        n = len(height)
        lefth = [-1] * n
        righth = [-1] * n
        # 左侧最高 
        lefth[0] = height[0]
        for i in range(1, n):
            lefth[i] = max(lefth[i-1], height[i])
        # 右侧最高
        righth[n-1] = height[n-1]
        for i in range(n-2, -1, -1):
            righth[i] = max(righth[i+1], height[i])

        res = 0
        for i in range(1, n - 1):
            h = min(lefth[i], righth[i]) - height[i]
            if h > 0:
                res += h 
        return res    
class Solution:
    # 采用单调栈,计算凹槽内的雨水
    # 单调栈内从底到头是递减的,
    # 1. 当前元素小于栈头,直接加入
    # 2. 当前元素等于栈头,替换栈头
    # 3. 当前元素大于栈头,形成凹槽,计算
    def trap(self, height: List[int]) -> int:
        res = 0
        n = len(height)
        stack = []
        stack.append(0)
        for i in range(1, n):
            # print("i:",i)
            # print("pre stack:",stack)
            # print("pre res:",res)
            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 = stack.pop()
                    if stack:
                        h = min(height[stack[-1]], height[i]) - height[mid]
                        w = i - stack[-1] - 1
                        res += h * w
                stack.append(i)
            # print("now stack:",stack)
            # print("now res:",res)
        return res     
class Solution:
    # 采用单调栈,计算凹槽内的雨水
    # 单调栈内从底到头是递减的,
    # 1. 当前元素小于栈头,直接加入
    # 2. 当前元素等于栈头,替换栈头
    # 3. 当前元素大于栈头,形成凹槽,计算
    def trap(self, height: List[int]) -> int:
        res = 0
        n = len(height)
        stack = []
        stack.append(0)
        for i in range(1, n):
            # print("i:",i)
            # print("pre stack:",stack)
            # print("pre res:",res)
            while stack and height[i] > height[stack[-1]]:
                mid = stack.pop()
                if stack:
                    h = min(height[stack[-1]], height[i]) - height[mid]
                    w = i - stack[-1] - 1
                    res += h * w
            stack.append(i)
            # print("now stack:",stack)
            # print("now res:",res)
        return res  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值