
代码求解
利用严格的大压小单调栈,找到每个位置数字左右两边离它最近且比它小的数字,确定以该数字为最小值的子数组的范围,通过计算开头和结尾的可能性确定字数租的个数,乘以该数字得到这部分子数组的最小值之和,每个数在弹出的时候都需要计算答案。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
class Solution {
public static int MAXN = 30001;
public static int MOD = 1000000007;
public static int[] stack = new int[MAXN];
public static int r;
public static int sumSubarrayMins(int[] arr){
long ans = 0;
for(int i=0;i<arr.length;i++){
while(r>0&&arr[stack[r-1]]>=arr[i]){
int cur = stack[--r];
int left = r==0?-1:stack[r-1];
ans = (ans+(long)(cur-left)*(i-cur)*arr[cur])%MOD;
}
stack[r++]=i;
}
while(r>0){
int cur = stack[--r];
int left = r==0?-1:stack[r-1];
ans = (ans+(long)(cur-left)*(arr.length-cur)*arr[cur])%MOD;
}
return (int)ans;
}
}
|