首页 > 其他分享 >力扣907. 子数组的最小值之和(单调栈)

力扣907. 子数组的最小值之和(单调栈)

时间:2023-11-27 20:33:48浏览次数:37  
标签:arr right 907 top long 力扣 最小值 empty size

给定一个整数数组 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

 

利用单调栈来找最小贡献值的边界,该题可参考题解

 1 class Solution {
 2 public:
 3 
 4     int sumSubarrayMins(vector<int>& arr) {
 5         long sum = 0;
 6         long mod = 1e9 + 7;
 7         long left[arr.size()],right[arr.size()];
 8         stack<long> s;
 9         for (long i = 0; i < arr.size(); ++i){
10             while (!s.empty() && arr[s.top()] > arr[i]){
11                 s.pop();
12             }
13             if (s.empty()){ //在0~i中arr[i]是最小的
14                 left[i] = -1;
15             }else{ //选取i左边第一个比他小的作为左边界
16                 left[i] = s.top();
17             }
18             s.push(i);
19         }
20         while(!s.empty()){
21             s.pop();
22         }
23         for (long i = arr.size() - 1;i >= 0; --i){
24             while(!s.empty() && arr[s.top()] >= arr[i]){
25                 s.pop();
26             }
27             if (s.empty()){
28                 right[i] = arr.size();
29             }else{
30                 right[i] = s.top();
31             }
32             s.push(i);
33         }
34         for (long i = 0;i < arr.size(); ++i){
35             sum += arr[i] * (i - left[i]) * (right[i] - i) % mod;
36         }
37         return sum % mod;
38     }
39 };

 

标签:arr,right,907,top,long,力扣,最小值,empty,size
From: https://www.cnblogs.com/coderhrz/p/17860379.html

相关文章

  • 907. 子数组的最小值之和(贡献法,单调栈,前后缀分解)
     题目不难,但是涉及到的知识点很丰富。classSolution:defsumSubarrayMins(self,arr:List[int])->int:MOD=10**9+7n=len(arr)pre=[-1]*nsuf=[n]*nstk=[]foriinrange(n):w......
  • mysql多个字段最大最小值
    转自:https://www.jb51.net/article/263686.htm1、语法最大值:GREATEST(expr_1,expr_2,...expr_n)最小值:LEAST(expr_1,expr_2,...expr_n)2、说明GREATEST(expr_1,expr_2,...expr_n)函数从表达式(列、常量、计算值)expr_1,expr_2,...expr_n等中找出最大的数返回......
  • 力扣刷题随笔
    力扣刷题随笔回文链表给你一个单链表的头节点head,请你判断该链表是否为回文链表。如果是,返回true;否则,返回false输入:head=[1,2,2,1]输出:true输入:head=[1,2]输出:false链表中节点数目在范围[1,105]内0<=Node.val<=9本题的思路就是利用双指针的方法来比......
  • P8907 [USACO22DEC] Making Friends P 题解
    明明看着不难的题目,却意外的卡人。思路考虑两头奶牛可以成为朋友条件是什么。存在一条路径连接这两头奶牛。且除去端点外的路径上的所有点的编号小于两端点的较小值。充分必要性都比较显然。如何维护。我们可以从小到大加入点,维护这些路径。对于每个点维护一个\(\text{se......
  • Python批量求取Excel表格每一个4行内某列的最大值、最小值
      本文介绍基于Python语言,基于Excel表格文件内某一列的数据,计算这一列数据在每一个指定数量的行的范围内(例如每一个4行的范围内)的区间最大值的方法。  已知我们现有一个.csv格式的Excel表格文件,其中有一列数据,我们希望对其加以区间最大值的计算——即从这一列的数据部分(也就是......
  • P7907 [Ynoi2005] rmscne 题解
    P7907[Ynoi2005]rmscne题解退役前的最后一篇题解,献给Ynoi。再见了各位。题目大意给定一个长度为\(n\)的序列和\(m\)次查询,对于每次查询,给定\(l,r\),求出一个最短的子区间\([l',r']\),满足所有在区间\([l,r]\)中出现的数也在\([l',r']\)中出现过。题解题还是很......
  • 力扣136
    136. 只出现一次的数字给你一个 非空 整数数组 nums ,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。你必须设计并实现线性时间复杂度的算法来解决此问题,且该算法只使用常量额外空间。思路①逐位异或②排序后找只出现一次的数复杂度思路②......
  • 力扣2760. 最长奇偶子数组
    给你一个下标从 0 开始的整数数组 nums 和一个整数 threshold 。请你从 nums 的子数组中找出以下标 l 开头、下标 r 结尾 (0<=l<=r<nums.length) 且满足以下条件的 最长子数组 :nums[l]%2==0对于范围 [l,r-1] 内的所有下标 i ,nums[i]%......
  • Codeforces Round 907 (Div. 2)
    \(A.SortingwithTwos\)https://codeforces.com/contest/1891/submission/232689614\(B.DejaVu\)https://codeforces.com/contest/1891/submission/232690141\(C.SmiloandMonsters\)https://codeforces.com/contest/1891/submission/232691988\(D.Suspic......
  • 力扣 075
    LCR075.数组的相对排序给定两个数组,arr1 和 arr2,arr2 中的元素各不相同arr2 中的每个元素都出现在 arr1 中对 arr1 中的元素进行排序,使 arr1 中项的相对顺序和 arr2 中的相对顺序相同。未在 arr2 中出现过的元素需要按照升序放在 arr1 的末尾。利用map计数,想的过......