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

Approach #1: Monotone Stack. [Java]

class Solution {
public int sumSubarrayMins(int[] A) {
int n = A.length;
Stack<int[]> in_stk_p = new Stack<>(), in_stk_n = new Stack<>();
// left is for the distance to previous less element
// right is for the distance to next less element.
int[] left = new int[n], right = new int[n];
for (int i = 0; i < n; ++i) left[i] = i + 1;
for (int i = 0; i < n; ++i) right[i] = n - i; for (int i = 0; i < n; ++i) {
while (!in_stk_p.isEmpty() && in_stk_p.peek()[0] > A[i]) in_stk_p.pop();
left[i] = in_stk_p.isEmpty() ? i + 1 : i - in_stk_p.peek()[1];
in_stk_p.push(new int[] {A[i], i}); while (!in_stk_n.isEmpty() && in_stk_n.peek()[0] > A[i]) {
int[] x = in_stk_n.peek();
in_stk_n.pop();
right[x[1]] = i - x[1];
}
in_stk_n.push(new int[] {A[i], i});
} int res = 0, mod = (int)1e9 + 7;
for (int i = 0; i < n; ++i)
res = (res + A[i]*left[i]*right[i]) % mod; return res;
}
}

  

Analysis:

Before diving into the solution, we first introduce a very important stack type, which is called momotone stack.

What is monotonous increase stack?

Roughly spkeaking, the elements in the an monotonous increase stack keeps an increasing order.

The typical paradigm for monotonous increase stack:

for(int i = 0; i < A.size(); i++){
while(!in_stk.empty() && in_stk.top() > A[i]){
in_stk.pop();
}
in_stk.push(A[i]);
}.

  

What can monotonous increase stack do?

(1) find the previous less element of each element in a vector with O(n) time:

What is the previous less element of an element?

For example:

[3, 7, 8, 4]

The previous less element of 7 is 3.

The previous less element of 8 is 7.

The previous less element of 4 is 3.

There are no previous less element for 3.

For simplicity of notation, we use abbreviation PLE to denote Previous Less Element.

C++ code (by slitghly modifying the paradigm):

Instead of directly pushing the element itself, here for simplicity, we push the incex.

We do some record when the index is pushed into the stack.

// previous_less[i] = j means A[j] is the previous less element of A[i].

// previous_less[i] = -1 means there is no previous less element of A[i].

vector<int> previous_less(A.size(), -1);
for(int i = 0; i < A.size(); i++){
while(!in_stk.empty() && A[in_stk.top()] > A[i]){
in_stk.pop();
}
previous_less[i] = in_stk.empty()? -1: in_stk.top();
in_stk.push(i);
}

  

(2) find the next less element of each element in a vector with O(n) time:

What is the next less element of an element?

For example:

[3, 7, 8, 4]

The next less element of 8 is 4.

The next less element of 7 is 4.

There is no next less element for 3 and 4.

For simplicity of notation, we use abbreviation NLE to denote Next Less Element.

C++ code (by slighly modifying the paradigm):

We do some record when the index is poped out from the stack.

// next_less[i] = j means A[j] is the next less element of A[i].

// next_less[i] = -1 mean there is no next less element of A[i].

vector<int> previous_less(A.size(), -1);
for(int i = 0; i < A.size(); i++){
while(!in_stk.empty() && A[in_stk.top()] > A[i]){
auto x = in_stk.top(); in_stk.pop();
next_less[x] = i;
}
in_stk.push(i);
}

  

How can the monotonous increase stack be applied to this problem?

For example:

Consider the element 3 in the following vector:

        [2, 9, 7, 8, 3, 4, 6, 1]

         |         |

    the previous less    the next less

      element of 3       element of 3

After finding both NLE and PLE of 3, we can determine the distance between 3 and 2(prevous less), and the distance between 3 and 1(next less). In this example, the distance is 4 and 3 respectively.

How many subarray with 3 being its minimum value?

The answer is 4 * 3.

How much the element 3 contributes to the final answer?

It is 3 * (3 * 4).

What is the final answer?

Denote  by left[i] the distance between element A[i] and its PLE.

Denote by right[i] the distance beween element A[i] and its NLE.

The final answer is:

sum(A[i] * left[i] * right[i])

Approach #2: Optimize [C++]

class Solution {
public:
int sumSubarrayMins(vector<int>& A) {
int res = 0, n = A.size(), mod = 1e9 + 7, j, k;
stack<int> s;
for (int i = 0; i <= n; ++i) {
while (!s.empty() && A[s.top()] > (i == n ? 0 : A[i])) {
j = s.top(), s.pop();
k = s.empty() ? -1 : s.top();
res = (res + A[j] * (i - j) * (j - k)) % mod;
}
s.push(i);
}
return res;
}
};

  

Analysis:

1. Here we record (A[i], i) in the stack. We can also only record index.

2. For left part and right part, the logic is same.

So for each, we used one stack and one pass.

This process can be optimized to one pass using one stack in total.

Reference:

https://leetcode.com/problems/sum-of-subarray-minimums/discuss/170750/C%2B%2BJavaPython-Stack-Solution

https://docs.oracle.com/javase/7/docs/api/java/util/Stack.html

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

907. Sum of Subarray Minimums的更多相关文章

  1. [LeetCode] 907. Sum of Subarray Minimums 子数组最小值之和

    Given an array of integers A, find the sum of min(B), where B ranges over every (contiguous) subarra ...

  2. 【leetcode】907. Sum of Subarray Minimums

    题目如下: 解题思路:我的想法对于数组中任意一个元素,找出其左右两边最近的小于自己的元素.例如[1,3,2,4,5,1],元素2左边比自己小的元素是1,那么大于自己的区间就是[3],右边的区间就是[4 ...

  3. [Swift]LeetCode907. 子数组的最小值之和 | Sum of Subarray Minimums

    Given an array of integers A, find the sum of min(B), where B ranges over every (contiguous) subarra ...

  4. 子数组最小值的总和 Sum of Subarray Minimums

    2018-09-27 23:33:49 问题描述: 问题求解: 方法一.DP(MLE) 动态规划的想法应该是比较容易想到的解法了,因为非常的直观,但是本题的数据规模还是比较大的,如果直接使用动态规划, ...

  5. leetcode907 Sum of Subarray Minimums

    思路: 对于每个数字A[i],使用单调栈找到A[i]作为最小值的所有区间数量,相乘并累加结果.时间复杂度O(n). 实现: class Solution { public: int sumSubarr ...

  6. LC 918. Maximum Sum Circular Subarray

    Given a circular array C of integers represented by A, find the maximum possible sum of a non-empty ...

  7. 动态规划-Maximum Subarray-Maximum Sum Circular Subarray

    2020-02-18 20:57:58 一.Maximum Subarray 经典的动态规划问题. 问题描述: 问题求解: public int maxSubArray(int[] nums) { i ...

  8. [Swift]LeetCode918. 环形子数组的最大和 | Maximum Sum Circular Subarray

    Given a circular array C of integers represented by A, find the maximum possible sum of a non-empty ...

  9. Maximum Sum Circular Subarray LT918

    Given a circular array C of integers represented by A, find the maximum possible sum of a non-empty ...

随机推荐

  1. Go开发之VScode安装

    1.找到官网 https://code.visualstudio.com/ 2根据自己机器环境下载 3.下载vscode地址,macos版本 https://vscode.cdn.azure.cn/s ...

  2. 纯css手写圆角气泡对话框 微信小程序和web都适用

    嗯……我们设计师强烈要求一定要圆角!圆角的气泡对话框,不要那种尖角的.这其中还遇上了个尴尬的问题,z-index不生效 无非就是两种方法,一种是使用图片再定位拼接起来使用,太简单了具体就不详细的说了. ...

  3. 2018.09.09 poj2949Word Rings(01分数规划+spfa判环)

    传送门 这题要先巧妙的转化一下. 对于每个字符串,我们把头尾的两个小字符串对应的点连边,边权是这个字符串的长度. 这样最多会出现26*26个点. 这个时候就只用求出边权和跟边数的最大比值了. 这个显然 ...

  4. 2018.07.06 POJ1698 Alice's Chance(最大流)

    Alice's Chance Time Limit: 1000MS Memory Limit: 10000K Description Alice, a charming girl, have been ...

  5. 右值引用和std::move函数(c++11)

    1.对象移动 1)C++11新标准中的一个最主要的特性就是移动而非拷贝对象的能力 2)优势: 在某些情况下,从旧内存拷贝到新内存是不必要的,此时对对象进行移动而非拷贝可以提升性能 有些类如IO类或un ...

  6. js 获取时间不能大于当前系统时间

    var dataDate=$.trim($("#dataDate").val()); if(dataDate.length==0){ $("#dataDateTip&qu ...

  7. addEvent兼容版

    function addEvent(elem,type,handle){ if (elem.addEventlistener) { elem.addEventlistener(type,handle, ...

  8. hdu 2153 仙人球的残影

    题目 这道题可以有两种写法: 第一种:找规律,如下: #include <stdio.h> int main() { int n,i,j,res; while (scanf("% ...

  9. 百度离线地图,web

    1.首先获取百度 JavaScript API 首先用浏览器打开 http://api.map.baidu.com/api?v=1.3 其中 http://api.map.baidu.com/gets ...

  10. Create Your Content and Structure

    The original page source Content is the most important aspect of any site. So let's design for the c ...