代码随想录 单调栈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
相关推荐
Jac_kie_層樓2 分钟前
力扣hot100刷题记录(12.2)
算法·leetcode·职场和发展
稚辉君.MCA_P8_Java31 分钟前
Gemini永久会员 C++返回最长有效子串长度
开发语言·数据结构·c++·后端·算法
京东零售技术1 小时前
下一代 Lakehouse 智能未来新引擎 | Apache Hudi Meetup亚洲站活动回顾
算法
京东零售技术1 小时前
NeurIPS 2025 | TANDEM:基于双层优化的数据配比学习方法
后端·算法
zmzb01031 小时前
C++课后习题训练记录Day42
开发语言·c++·算法
CoovallyAIHub1 小时前
MAR-YOLOv9:革新农业检测,YOLOv9的“低调”逆袭
深度学习·算法·计算机视觉
Mr Lee_2 小时前
Smali 文件生成dex装箱算法整合
开发语言·python·算法
LDG_AGI2 小时前
【推荐系统】深度学习训练框架(十三):模型输入——《特征索引》与《特征向量》的边界
人工智能·pytorch·分布式·深度学习·算法·机器学习
CoovallyAIHub2 小时前
如何让SAM3在医学图像上比专用模型还强?一个轻量Adapter如何让它“秒变”专家?
深度学习·算法·计算机视觉
suoge2232 小时前
热传导控制方程有限元弱形式推导-有限元编程入门
算法