# Sum of minimum elements of all subarrays

• Difficulty Level : Hard
• Last Updated : 04 Jul, 2022

Given an array A of n integers. The task is to find the sum of minimum of all possible (contiguous) subarray of A.
Examples:

Input: A = [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.
Input : A = [1, 2, 3, 4]
Output : 20

Approach: The Naive approach is to generate all possible (contiguous) subarrays, find their minimum and add them to result. The time complexity will be O(N2).
Efficient Approach: The general intuition for solution to the problem is to find sum(A[i] * f(i)), where f(i) is the number of subarrays in which A[i] is the minimum.
In order to find f[i], we need to find out:
left[i], the length of strictly larger numbers on the left of A[i]
right[i], the length of larger numbers on the right of A[i].
We make two arrays left[ ] and right[ ] such that:
left[i] + 1 equals to the number of subarrays ending with A[i], and A[i] is only single minimum.
Similarly, right[i] + 1 equals to the number of subarrays starting with A[i], and A[i] is first minimum.
Finally, f(i) = (left[i]) * (right[i]), where f[i] equals total number of subarrays in which A[i] is minimum.x
Below is the implementation of above approach

## C++

 `// CPP implementation of above approach``#include ``using` `namespace` `std;` `// Function to return required minimum sum``int` `sumSubarrayMins(``int` `A[], ``int` `n)``{``    ``int` `left[n], right[n];` `    ``stack > s1, s2;` `    ``// getting number of element strictly larger``    ``// than A[i] on Left.``    ``for` `(``int` `i = 0; i < n; ++i) {``        ``int` `cnt = 1;` `        ``// get elements from stack until element``        ``// greater than A[i] found``        ``while` `(!s1.empty() && (s1.top().first) > A[i]) {``            ``cnt += s1.top().second;``            ``s1.pop();``        ``}` `        ``s1.push({ A[i], cnt });``        ``left[i] = cnt;``    ``}` `    ``// getting number of element larger than A[i] on Right.``    ``for` `(``int` `i = n - 1; i >= 0; --i) {``        ``int` `cnt = 1;` `        ``// get elements from stack until element greater``        ``// or equal to A[i] found``        ``while` `(!s2.empty() && (s2.top().first) >= A[i]) {``            ``cnt += s2.top().second;``            ``s2.pop();``        ``}` `        ``s2.push({ A[i], cnt });``        ``right[i] = cnt;``    ``}` `    ``int` `result = 0;` `    ``// calculating required resultult``    ``for` `(``int` `i = 0; i < n; ++i)``        ``result = (result + A[i] * left[i] * right[i]);` `    ``return` `result;``}` `// Driver program``int` `main()``{``    ``int` `A[] = { 3, 1, 2, 4 };` `    ``int` `n = ``sizeof``(A) / ``sizeof``(A[0]);` `    ``// function call to get required resultult``    ``cout << sumSubarrayMins(A, n);` `    ``return` `0;``}``// This code is written by Sanjit_Prasad`

## Java

 `// Java implementation of above approach``import` `java.util.*;` `class` `GFG``{``static` `class` `pair``{``    ``int` `first, second;``    ``public` `pair(``int` `first, ``int` `second)``    ``{``        ``this``.first = first;``        ``this``.second = second;``    ``}``}` `// Function to return required minimum sum``static` `int` `sumSubarrayMins(``int` `A[], ``int` `n)``{``    ``int` `[]left = ``new` `int``[n];``    ``int` `[]right = ``new` `int``[n];` `    ``Stack s1 = ``new` `Stack();``    ``Stack s2 = ``new` `Stack();``    ` `    ``// getting number of element strictly larger``    ``// than A[i] on Left.``    ``for` `(``int` `i = ``0``; i < n; ++i)``    ``{``        ``int` `cnt = ``1``;` `        ``// get elements from stack until element``        ``// greater than A[i] found``        ``while` `(!s1.isEmpty() &&``               ``(s1.peek().first) > A[i])``        ``{``            ``cnt += s1.peek().second;``            ``s1.pop();``        ``}` `        ``s1.push(``new` `pair(A[i], cnt));``        ``left[i] = cnt;``    ``}` `    ``// getting number of element larger``    ``// than A[i] on Right.``    ``for` `(``int` `i = n - ``1``; i >= ``0``; --i)``    ``{``        ``int` `cnt = ``1``;` `        ``// get elements from stack until element``        ``// greater or equal to A[i] found``        ``while` `(!s2.isEmpty() &&``               ``(s2.peek().first) >= A[i])``        ``{``            ``cnt += s2.peek().second;``            ``s2.pop();``        ``}` `        ``s2.push(``new` `pair(A[i], cnt));``        ``right[i] = cnt;``    ``}` `    ``int` `result = ``0``;` `    ``// calculating required resultult``    ``for` `(``int` `i = ``0``; i < n; ++i)``        ``result = (result + A[i] * left[i] *``                                  ``right[i]);` `    ``return` `result;``}` `// Driver Code``public` `static` `void` `main(String[] args)``{``    ``int` `A[] = { ``3``, ``1``, ``2``, ``4` `};` `    ``int` `n = A.length;` `    ``// function call to get required result``    ``System.out.println(sumSubarrayMins(A, n));``}``}` `// This code is contributed by PrinciRaj1992`

## Python3

 `# Python3 implementation of above approach` `# Function to return required minimum sum``def` `sumSubarrayMins(A, n):` `    ``left, right ``=` `[``None``] ``*` `n, [``None``] ``*` `n``    ` `    ``# Use list as stack``    ``s1, s2 ``=` `[], []` `    ``# getting number of element strictly``    ``# larger than A[i] on Left.``    ``for` `i ``in` `range``(``0``, n):``        ``cnt ``=` `1` `        ``# get elements from stack until``        ``# element greater than A[i] found``        ``while` `len``(s1) > ``0` `and` `s1[``-``1``][``0``] > A[i]:``            ``cnt ``+``=` `s1[``-``1``][``1``]``            ``s1.pop()` `        ``s1.append([A[i], cnt])``        ``left[i] ``=` `cnt` `    ``# getting number of element``    ``# larger than A[i] on Right.``    ``for` `i ``in` `range``(n ``-` `1``, ``-``1``, ``-``1``):``        ``cnt ``=` `1` `        ``# get elements from stack until``        ``# element greater or equal to A[i] found``        ``while` `len``(s2) > ``0` `and` `s2[``-``1``][``0``] >``=` `A[i]:``            ``cnt ``+``=` `s2[``-``1``][``1``]``            ``s2.pop()` `        ``s2.append([A[i], cnt])``        ``right[i] ``=` `cnt` `    ``result ``=` `0` `    ``# calculating required resultult``    ``for` `i ``in` `range``(``0``, n):``        ``result ``+``=` `A[i] ``*` `left[i] ``*` `right[i]` `    ``return` `result` `# Driver Code``if` `__name__ ``=``=` `"__main__"``:` `    ``A ``=` `[``3``, ``1``, ``2``, ``4``]``    ``n ``=` `len``(A)` `    ``# function call to get``    ``# required resultult``    ``print``(sumSubarrayMins(A, n))` `# This code is contributed``# by Rituraj Jain`

## C#

 `// C# implementation of above approach``using` `System;``using` `System.Collections.Generic;` `class` `GFG``{``public` `class` `pair``{``    ``public` `int` `first, second;``    ``public` `pair(``int` `first, ``int` `second)``    ``{``        ``this``.first = first;``        ``this``.second = second;``    ``}``}` `// Function to return required minimum sum``static` `int` `sumSubarrayMins(``int` `[]A, ``int` `n)``{``    ``int` `[]left = ``new` `int``[n];``    ``int` `[]right = ``new` `int``[n];` `    ``Stack s1 = ``new` `Stack();``    ``Stack s2 = ``new` `Stack();``    ` `    ``// getting number of element strictly larger``    ``// than A[i] on Left.``    ``for` `(``int` `i = 0; i < n; ++i)``    ``{``        ``int` `cnt = 1;` `        ``// get elements from stack until element``        ``// greater than A[i] found``        ``while` `(s1.Count!=0 &&``            ``(s1.Peek().first) > A[i])``        ``{``            ``cnt += s1.Peek().second;``            ``s1.Pop();``        ``}` `        ``s1.Push(``new` `pair(A[i], cnt));``        ``left[i] = cnt;``    ``}` `    ``// getting number of element larger``    ``// than A[i] on Right.``    ``for` `(``int` `i = n - 1; i >= 0; --i)``    ``{``        ``int` `cnt = 1;` `        ``// get elements from stack until element``        ``// greater or equal to A[i] found``        ``while` `(s2.Count != 0 &&``              ``(s2.Peek().first) >= A[i])``        ``{``            ``cnt += s2.Peek().second;``            ``s2.Pop();``        ``}` `        ``s2.Push(``new` `pair(A[i], cnt));``        ``right[i] = cnt;``    ``}` `    ``int` `result = 0;` `    ``// calculating required resultult``    ``for` `(``int` `i = 0; i < n; ++i)``        ``result = (result + A[i] * left[i] *``                                  ``right[i]);` `    ``return` `result;``}` `// Driver Code``public` `static` `void` `Main(String[] args)``{``    ``int` `[]A = { 3, 1, 2, 4 };` `    ``int` `n = A.Length;` `    ``// function call to get required result``    ``Console.WriteLine(sumSubarrayMins(A, n));``}``}` `// This code is contributed by Rajput-Ji`

## Javascript

 ``

Output

`17`

Time Complexity: O(N), where N is the length of A.
Space Complexity: O(N).

Another Approach

It is a dynamic programming approach

First, calculate the next smaller element index on the right side for each index using stacks.

At any index i, dp[i] denotes the total sum of all the sub-arrays starting from index i.

For calculating the answer for each index, there will be two cases :

1. The current element is the smallest element amongst all the elements on the right-hand side. So ans will be (( range of curr_index *  arr[curr_index] )) . As it will be the smallest element in all the sub-arrays starting from  curr_index.
• There is an element present on right, which is smaller than the current element. Answer from that smaller_element is already stored in dp. Just Calculate the answer from current_index to smaller_right_index.
• upto_smaller = (right_index – curr_index)*arr[curr_index]     ## sum up to right smaller index form curr_index .
• curr_sum = upto_smaller + dp[right_index]

Finally , return the sum(dp).

For eg :- arr = [4,3,6]

dp[6] = 6

dp[3] => (3-1)*3 => 6     #smallest element

dp[4] = (1 -0) *(4) + dp[3]  => 4 + 6 => 10

Final answer = 6 + 6 + 10= 22

## C++

 `// C++ program to implement the approach``#include ` `using` `namespace` `std;` `int` `sumSubarrayMins(``int` `arr[], ``int` `n)``{``    ``int` `dp[n];``    ``for` `(``int` `i = 0; i < n; i++)``        ``dp[i] = 0;` `    ``// calculate right smaller element``    ``int` `right[n];` `    ``for` `(``int` `i = 0; i < n; i++) {``        ``right[i] = i;``    ``}``    ``vector<``int``> stack{ 0 };` `    ``for` `(``int` `i = 1; i < n; i++) {` `        ``int` `curr = arr[i];``        ``while` `((stack.size() > 0)``               ``&& (curr < arr[stack.back()])) {` `            ``int` `idx = stack.back();``            ``stack.pop_back();``            ``right[idx] = i;``        ``}``        ``stack.push_back(i);``    ``}` `    ``dp[n - 1] = arr[n - 1];` `    ``for` `(``int` `i = n - 2; i >= 0; i--) {` `        ``int` `right_idx = right[i];``        ``if` `(right_idx == i) { ``// case 1` `            ``int` `curr = (n - i) * arr[i];``            ``dp[i] = curr;``        ``}` `        ``else` `{ ``// case 2` `            ``// sum upto next smaller rhs element``            ``int` `upto_small = (right_idx - i) * (arr[i]);` `            ``int` `curr_sum = (upto_small + dp[right_idx]);``            ``dp[i] = curr_sum;``        ``}``    ``}``    ` `      ``//calculating sum of dp``    ``int` `sum = 0;``    ``sum = accumulate(dp, dp + n, sum);``    ``return` `sum;``}` `// Driver Code``int` `main()``{``    ``int` `A[] = { 3, 1, 2, 4 };``    ``int` `n = ``sizeof``(A) / ``sizeof``(A[0]);` `    ``// function call to get``    ``// required result``    ``cout << sumSubarrayMins(A, n) << endl;``}` `// This code is contributed by phasing17`

## Java

 `// Java program to implement the approach``import` `java.util.*;` `public` `class` `GFG {` `  ``static` `int` `sumSubarrayMins(``int``[] arr, ``int` `n)``  ``{``    ``int` `dp[] = ``new` `int``[n];``    ``for` `(``int` `i = ``0``; i < n; i++)``      ``dp[i] = ``0``;` `    ``// calculate right smaller element``    ``int` `right[] = ``new` `int``[n];` `    ``for` `(``int` `i = ``0``; i < n; i++) {``      ``right[i] = i;``    ``}``    ``ArrayList stack = ``new` `ArrayList();``    ``stack.add(``0``);` `    ``for` `(``int` `i = ``1``; i < n; i++) {` `      ``int` `curr = arr[i];``      ``while` `(``        ``(stack.size() > ``0``)``        ``&& (curr``            ``< arr[stack.get(stack.size() - ``1``)])) {` `        ``int` `idx = stack.get(stack.size() - ``1``);``        ``stack.remove(stack.size() - ``1``);``        ``right[idx] = i;``      ``}``      ``stack.add(i);``    ``}` `    ``dp[n - ``1``] = arr[n - ``1``];` `    ``for` `(``int` `i = n - ``2``; i >= ``0``; i--) {` `      ``int` `right_idx = right[i];``      ``if` `(right_idx == i) { ``// case 1` `        ``int` `curr = (n - i) * arr[i];``        ``dp[i] = curr;``      ``}` `      ``else` `{ ``// case 2` `        ``// sum upto next smaller rhs element``        ``int` `upto_small = (right_idx - i) * (arr[i]);` `        ``int` `curr_sum = (upto_small + dp[right_idx]);``        ``dp[i] = curr_sum;``      ``}``    ``}` `    ``// calculating sum of dp``    ``int` `sum = ``0``;` `    ``for` `(``int` `i = ``0``; i < dp.length; i++)``      ``sum += dp[i];` `    ``return` `sum;``  ``}` `  ``// Driver Code``  ``public` `static` `void` `main(String[] args)``  ``{``    ``int` `A[] = { ``3``, ``1``, ``2``, ``4` `};``    ``int` `n = A.length;` `    ``// function call to get``    ``// required result``    ``System.out.println(sumSubarrayMins(A, n));``  ``}``}` `// This code is contributed by phasing17`

## Python3

 `def` `sumSubarrayMins(arr, n):``    ` `    ``dp ``=` `[``0``]``*``(n)``    ` `    ``# calculate right smaller element``    ``right ``=` `[i ``for` `i ``in` `range``(n)] ``    ``stack ``=` `[``0``]` `    ``for` `i ``in` `range``(``1``,n,``1``):` `        ``curr ``=` `arr[i]``        ``while``(stack ``and` `curr < arr[stack[``-``1``]]):` `            ``idx ``=` `stack.pop()``            ``right[idx] ``=` `i` `        ``stack.append(i)` `    ``dp[``-``1``] ``=` `arr[``-``1``]` `    ``for` `i ``in` `range``(n``-``2``,``-``1``,``-``1``):` `        ``right_idx ``=` `right[i]    ``        ``if` `right_idx ``=``=` `i:     ``# case 1` `            ``curr ``=` `(n``-``i)``*``arr[i]``            ``dp[i] ``=` `curr` `        ``else``:   ``# case 2``          ` `            ``# sum upto next smaller rhs element``            ``upto_small ``=` `(right_idx``-``i)``*``(arr[i])  ``            ` `            ``curr_sum ``=` `(upto_small ``+` `dp[right_idx])``            ``dp[i] ``=` `curr_sum` `    ``return` `(``sum``(dp))``    ` `    ` `# Driver Code``if` `__name__ ``=``=` `"__main__"``:``    ``A ``=` `[``3``, ``1``, ``2``, ``4``]``    ``n ``=` `len``(A)``    ` `    ``# function call to get``    ``# required resultult``    ``print``(sumSubarrayMins(A, n))`

## Javascript

 ``

Output

`17`

Time and Space Complexity := O(N)

My Personal Notes arrow_drop_up