首页 > 其他分享 >LeetCode/子数组的最小值之和

LeetCode/子数组的最小值之和

时间:2023-05-19 17:35:34浏览次数:39  
标签:arr int back long 最小值 数组 ans monoStack LeetCode

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

1. 单调栈

假如要遍历所有区间,哪怕可以直接获得最小值,时间复杂度也是O(n2
这里我们不逐个找对应区间,而是计算每个值对区间的贡献,可以将时间复杂度降到O(n)
其实也就找遍历时当前值的左边界和右边界,在这个区间内该值为最小值,即可直接计算出,该值会对多少个区间做出贡献
先用单调栈找左右两边下一个更小值的坐标即可

class Solution {
public:
    int sumSubarrayMins(vector<int>& arr) {
        int n = arr.size();
        vector<int> monoStack; //单调栈
        vector<int> left(n), right(n);//左右边界
        for (int i = 0; i < n; i++) {//从左往右找左边更小值
            while (!monoStack.empty() && arr[i] <= arr[monoStack.back()]) {//把更大的值挤出来,相等的视为更大,区间计算的时候不影响
                monoStack.pop_back();
            }
            left[i] = i - (monoStack.empty() ? -1 : monoStack.back()); //左区间长度
            monoStack.emplace_back(i);//放入坐标
        }
        monoStack.clear();
        for (int i = n - 1; i >= 0; i--) { //从右往左找右边更小值
            while (!monoStack.empty() && arr[i] < arr[monoStack.back()]) {
                monoStack.pop_back();
            }
            right[i] = (monoStack.empty() ? n : monoStack.back()) - i; //右区间长度
            monoStack.emplace_back(i);
        }
        long long ans = 0;
        long long mod = 1e9 + 7;
        for (int i = 0; i < n; i++) { //计算每个值的贡献
            ans = (ans + (long long)left[i] * right[i] * arr[i]) % mod; 
        }
        return ans;
    }
};


标签:arr,int,back,long,最小值,数组,ans,monoStack,LeetCode
From: https://www.cnblogs.com/929code/p/17415817.html

相关文章

  • 数组的常用方法
    <!--作者:zhangfan页面名称:数组的常用方法--><template><divclass="topCon"><el-buttontype="primary"@click="clickBtn">主要按钮</el-button></div></template><script>exportdefault......
  • [LeetCode] 1079. Letter Tile Possibilities
    Youhave n  tiles,whereeachtilehasoneletter tiles[i] printedonit.Return thenumberofpossiblenon-emptysequencesofletters youcanmakeusingthelettersprintedonthose tiles.Example1:Input:tiles="AAB"Output:8Explanation:......
  • [learn from chatGPT] [vba] 如何使用 Collection 或 Dictionary 对象来代替数组
    在VBA中,`Collection`和`Dictionary`对象可以用来代替数组。它们的主要优点是可以动态地添加、删除和查找元素,而无需调整数组大小。下面是一个简单的例子:```SubUseCollection()DimmyCollectionAsNewCollection'添加元素到Collection中myCollection.Add......
  • LeetCode/完成任务的最少工作时间段
    一个工作时间段可以连续工作sessiontime个小时给你任务列表task,task[i]表示第i项任务花费时间求完成全部工作所需最小时间段(可以按任意顺序完成任务)1.回溯法回溯时按任务下标推进,边界条件为任务下标等于任务长度同时要记录回溯几个状态,分别是当前任务下标、已用时间段、各......
  • 微信小程序setData()对数组的操作
    对于setData普通数据类型而言,没什么讲究但是对于数组而言,再直接修改一个完整的数组显得有些多余,首先写着不简易,其次效率很是滴。比如你都能觉得复杂,官方肯定是有对应的优化的。官方demoPage({data:{array:[{text:'initdata'}],},changeItemInArray:fun......
  • 二刷Leetcode-Days06
    二叉树:/***迭代法实现中序前序后序遍历*@paramroot*@return*/publicList<Integer>preorderTraversalIterator(TreeNoderoot){List<Integer>result=newArrayList<>();if(root==null){ret......
  • #yyds干货盘点# LeetCode程序员面试金典: 二叉树的层序遍历 II
    1.简述:给你二叉树的根节点root,返回其节点值自底向上的层序遍历。(即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历) 示例1:输入:root=[3,9,20,null,null,15,7]输出:[[15,7],[9,20],[3]]示例2:输入:root=[1]输出:[[1]]示例3:输入:root=[]输出:[]2.代码实现:classSolution......
  • 2023-05-18:有 n 名工人。 给定两个数组 quality 和 wage , 其中,quality[i] 表示第 i 名
    2023-05-18:有n名工人。给定两个数组quality和wage,其中,quality[i]表示第i名工人的工作质量,其最低期望工资为wage[i]。现在我们想雇佣k名工人组成一个工资组。在雇佣一组k名工人时,我们必须按照下述规则向他们支付工资:对工资组中的每名工人,应当按其工作质量与同组其......
  • 2023-05-18:有 n 名工人。 给定两个数组 quality 和 wage , 其中,quality[i] 表示第 i 名
    2023-05-18:有n名工人。给定两个数组quality和wage,其中,quality[i]表示第i名工人的工作质量,其最低期望工资为wage[i]。现在我们想雇佣k名工人组成一个工资组。在雇佣一组k名工人时,我们必须按照下述规则向他们支付工资:对工资组中的每名工人,应当按其工作质量与同......
  • 数组
    数组数组的定义数组是相同型数据的有序集合。数组描述的是相同类型的若干个数据,按照一定的先后次序排列组合而成。其中,每一个数据称作一个数组元素,每个数组元素可以通过一个下标来访问它们。数组的声明和创建首先必须声明数组变量,才能在程序中使用数组。下面是声明数组的语......