代码随想录 单调栈part2

  1. 下一个更大元素 II

给定一个循环数组 numsnums[nums.length - 1] 的下一个元素是 nums[0] ),返回 nums 中每个元素的 下一个更大元素

数字 x下一个更大的元素 是按数组遍历顺序,这个数字之后的第一个比它更大的数,这意味着你应该循环地搜索它的下一个更大的数。如果不存在,则输出 -1

思路:在后面多续一段

python 复制代码
class Solution:
    def nextGreaterElements(self, nums: List[int]) -> List[int]:
        dp = [-1] * len(nums)
        stack = []
        for i in range(len(nums)*2):
            while(len(stack) != 0 and nums[i%len(nums)] > nums[stack[-1]]):
                dp[stack[-1]] = nums[i%len(nums)]
                stack.pop()
            stack.append(i%len(nums))
        return dp
  1. 接雨水

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

思路:

  1. 双指针(dp):从列的角度去看,每一列可以装的雨水取决于左边最高的柱子和右边最高的柱子和该列的高度的差。可以使用双指针,当前列的左边最高的柱子可以由前一列的左边最高柱子转移而来,同理列的右边最高的柱子可以由后一列的左边最高柱子转移而来。
python 复制代码
class Solution:
    def trap(self, height: List[int]) -> int:
        left_dp = [0 for _ in range(len(height))]  # 记录左边最高的柱子

        right_dp = [0 for _ in range(len(height))]  # 记录右边最高的柱子

        ans = 0
        left_max= 0
        right_max = 0
        for i in range(1, len(height)):  # 求每一列左边最高的柱子
            left_dp[i] = max(left_dp[i-1], height[i-1])
        
        for j in range(len(height) -2 , 0, -1):  # 求每一列右边最高的柱子
            right_dp[j] = max(right_dp[j+1], height[j+1])
        
        for k in range(len(height)):  # 求可以接住的雨水
            h = min(left_dp[k], right_dp[k]) - height[k]
            ans += max(0, h)

        return ans
  1. 单调栈

从行的角度去看,需要找到一个个凹槽,大的凹槽又有小凹槽,可以将凹槽都归一为底部平坦的凹槽,如果有小凹槽,再计算小凹槽的积水量后,就认为其填上了,这样每一个凹槽都是底部平坦的凹槽,凹槽积水量就是 雨水高度 * 雨水深度,其中雨水高度为min(凹槽左侧高度, 凹槽右侧高度) - 凹槽底部高度,雨水宽度是 凹槽右侧的下标 - 凹槽左侧的下标 - 1。找的是该元素左边和右边第一个大于该元素的位置和高度,可以用单调栈。

单调栈性质,从栈头到栈尾单调递增,当遇到比栈头元素大的就是出现凹槽,计算凹槽的雨水体积。

python 复制代码
class Solution:
    def trap(self, height: List[int]) -> int:
   
        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]]:
                continue
    
            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
                        w = i - stack[-1] - 1
                       
                        result += h * w
                stack.append(i)
        return result
相关推荐
No0d1es4 小时前
电子学会青少年软件编程(C/C++)5级等级考试真题试卷(2024年6月)
c语言·c++·算法·青少年编程·电子学会·五级
大阳1236 小时前
线程(基本概念和相关命令)
开发语言·数据结构·经验分享·算法·线程·学习经验
weixin_307779137 小时前
VS Code配置MinGW64编译GNU 科学库 (GSL)
开发语言·c++·vscode·算法
学行库小秘8 小时前
ANN神经网络回归预测模型
人工智能·python·深度学习·神经网络·算法·机器学习·回归
没落之殇8 小时前
基于C语言实现的HRV分析方法 —— 与Kubios和MATLAB对比
算法
秋难降8 小时前
线段树的深度解析(最长递增子序列类解题步骤)
数据结构·python·算法
楚韵天工9 小时前
基于GIS的无人机模拟飞行控制系统设计与实现
深度学习·算法·深度优先·无人机·广度优先·迭代加深·图搜索算法
你也向往长安城吗10 小时前
推荐一个三维导航库:three-pathfinding-3d
javascript·算法
百度智能云10 小时前
VectorDB+FastGPT一站式构建:智能知识库与企业级对话系统实战
算法
AI小白的Python之路11 小时前
数据结构与算法-排序
数据结构·算法·排序算法