• 单调栈907. 子数组的最小值之和


    2022-05-25 21:40:29

    问题描述:

    给定一个整数数组 arr,找到 min(b) 的总和,其中 b 的范围为 arr 的每个(连续)子数组。

    由于答案可能很大,因此 返回答案模 10^9 + 7 。

    示例 1:

    输入:arr = [3,1,2,4]
    输出:17
    解释:
    子数组为 [3],[1],[2],[4],[3,1],[1,2],[2,4],[3,1,2],[1,2,4],[3,1,2,4]。
    最小值为 3,1,2,4,1,1,2,1,1,1,和为 17。
    示例 2:

    输入:arr = [11,81,94,43,3]
    输出:444
     

    提示:

    1 <= arr.length <= 3 * 104
    1 <= arr[i] <= 3 * 104

    问题求解:

    本题需要考虑每个元素的管辖范围:对应nums[i]以其为最小值的范围[l, r]。

    这一步可以通过单调栈求得。

    但有一点需要特别注意:去重。

    这里的去重逻辑是采用单边逻辑,例如取左边第一个小于nums[i]的位置,取右边第一个小于等于nums[i]的位置。

    class Solution:
        def sumSubarrayMins(self, arr: List[int]) -> int:
            n = len(arr)
            left = [0] * n
            right = [0] * n
            stk = []
            for i in range(n - 1, -1, -1):
                while stk and arr[stk[-1]] > arr[i]:
                    stk.pop()
                right[i] = stk[-1] - i if stk else n - i
                stk.append(i)
            stk = []
            for i in range(n):
                while stk and arr[stk[-1]] >= arr[i]:
                    stk.pop()
                left[i] = i - stk[-1] if stk else i + 1
                stk.append(i)
            
            res = 0
            mod = int(1e9 + 7)
            for i in range(n):
                res = (res + arr[i] * left[i] * right[i]) % mod
            return res
    

      

  • 相关阅读:
    【java】java 中 byte[]、File、InputStream 互相转换
    【java】java base64编码与解码
    git初级使用教程
    git学习五:eclipse使用git下载项目
    git学习四:eclipse使用git提交项目
    mybatis连接mysql数据库插入中文乱码
    SpringMVC加载配置Properties文件的几种方式
    zip 压缩文件夹
    java IOUtils下载图片
    spring工具类获取bean
  • 原文地址:https://www.cnblogs.com/hyserendipity/p/16311043.html
Copyright © 2020-2023  润新知