Given an array of integers A
, find the sum of min(B)
, where B
ranges over every (contiguous) subarray of A
.
Since the answer may be large, return the answer modulo 10^9 + 7.
Example 1:
1 | Input: [3,1,2,4] |
解法1
统计以a[j]为right-most最小值的子数组的个数, 记作s[j].这样, 结果就是sum(s[j] * a[j]). 必须以right-most为条件,因为只有如此,才能把子数组分为不重合的集合以免重复计算.
问题于是转化为, 求最小的i(i<=j), a[i] , a[i+1] , …., a[j]都是大于等于a[j]的.以及最大的k(k>=j) , a[j+1], a[j+2],….,a[k]都大于a[j].然后问题可以进一步转化为找出位置j左边距离j位置最近且值比arr[j]小的位置,同时找出位置j右边距离j位置最近且值小于等于arr[j]的位置.
那么,假设位置j左边距离位置j最近且值比arr[j]小的位置为i,且位置j右边距离位置j最近且值小于等于arr[j]的位置为k,那么位置j左边有(i-1)-(k+1) + 1=i-k-1个元素大于等于arr[j],同时,位置j右边有(k-1)-(i+1)-1 = k - i + 1个元素比arr[j]大.那么,以arr[j]为right-most最小值的子数组个数有(i-k) * (k-j)个.
对于一个数组[5,3,4,6]来说,包含3的子数组有6个.
这是因为3的左边有一个数, 右边有2个数.3可以在它的左边选择0个或者1个数, 在右边选择0或1个或2个构成子数组.因为包括3的子数组个数共有6个,分别是:
即包括3的子数组的个数是(j - i - 1) * (k - j - 1), 设j=1表示3的索引, i=-1,k = 4.
1 | [[3],[5,3],[3,4],[3,4,6], [5,3,4],[5,3,4,6]] |
过程
设a = [3,2,2,4].则对于第一个2来说,以它为right-most最小值的子数组有:[[2],[3,2]],以第二个2为right-most最小值的子数组有:[[2],[2,2],[2,4],[3,2,2],[2,2,4],[3,2,2,4]],共6个,因为在第二个2之前有两个数[3,2]都大于等于它,而在它之后有一个数小于等于它,则以第二个2为right-most最小值的子数组共有(2+1) * (1+1) = 6个.
然后使用单调栈来求数组a中a[j]左边第一个小于a[j]的元素a[i]和右边第一个小于等于a[j]的元素a[k].
1 | /*** |
AC代码
1 | class Solution { |