907. Sum of Subarray Minimums

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:

Input: [3,1,2,4]
Output: 17
Explanation: Subarrays are [3], [1], [2], [4], [3,1], [1,2], [2,4], [3,1,2], [1,2,4], [3,1,2,4]. 
Minimums are 3, 1, 2, 4, 1, 1, 2, 1, 1, 1.  Sum is 17.

 

Note:

  1. 1 <= A.length <= 30000
  2. 1 <= A[i] <= 30000

https://leetcode.com/problems/sum-of-subarray-minimums/discuss/178876/stack-solution-with-very-detailed-explanation-step-by-step

class Solution {
    public int sumSubarrayMins(int[] A) {
        int len = A.length;
        Stack<Integer> stack = new Stack<>();
        int[] left = new int[len];
        int[] right = new int[len];
        for(int i = 0; i < A.length; i++) {
            left[i] = i + 1;
            right[i] = len - i;
        }
        // previous less element
        for(int i = 0; i < len; i++){
            while(!stack.isEmpty() && A[stack.peek()] > A[i]) {
                stack.pop();
            }
            left[i] = stack.isEmpty() ? i + 1 : i - stack.peek();
            stack.push(i);
        }
        //next less element
        stack = new Stack<>();
        for(int i = 0; i < len; i++){
            while(!stack.isEmpty() && A[stack.peek()] > A[i]) {
                right[stack.peek()] = i - stack.peek();
                stack.pop();
            }
            stack.push(i);
        }
        int ans = 0;
        int mod = (int)1e9 + 7;
        for(int i = 0; i < len; i++) {
            ans = (ans + A[i] * left[i] * right[i]) % mod;
        }
        return ans;
    }
}

https://www.cnblogs.com/grandyang/p/8887985.html

monotonic stack

何为单调栈?就是一个单调递增/递减的栈。这题用的是递增栈,找的是左右小的数(的index)

这道题中,我们找到每个元素和左边第一个比他小的元素的距离,以及右边第一个比它小的元素的距离,他俩相乘就是当前元素在多少个子集中充当了最小元素。

初始化时也很玄妙,找左边时,初始化为i+1,如果左边没有比他小的说明他自己就是最小的,在左边i+1个数中充当了最小元素。

找右边时,初始化为length - i,比如i == 0,如果它是最小元素,说明右边没有比它还小的了,

posted @ 2020-08-15 13:40  Schwifty  阅读(110)  评论(0编辑  收藏  举报