Skip to content
Related Articles

Related Articles

Improve Article
Sum of minimum elements of all subarrays
  • Difficulty Level : Hard
  • Last Updated : 10 Jun, 2021

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.
Below is the implementation of above approach 
 

C++




// CPP implementation of above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to return required minimum sum
int sumSubarrayMins(int A[], int n)
{
    int left[n], right[n];
 
    stack<pair<int, int> > 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<pair> s1 = new Stack<pair>();
    Stack<pair> s2 = new Stack<pair>();
     
    // 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<pair> s1 = new Stack<pair>();
    Stack<pair> s2 = new Stack<pair>();
     
    // 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




<script>
  
// JavaScript implementation of above approach
 
// Function to return required minimum sum
function sumSubarrayMins(A, n)
{
    var left = Array(n), right = Array(n);
 
    var s1 = [], s2 = [];
 
    // getting number of element strictly larger
    // than A[i] on Left.
    for (var i = 0; i < n; ++i) {
        var cnt = 1;
 
        // get elements from stack until element
        // greater than A[i] found
        while (s1.length!=0 && (s1[s1.length-1][0]) > A[i]) {
            cnt += s1[s1.length-1][1];
            s1.pop();
        }
 
        s1.push([A[i], cnt]);
        left[i] = cnt;
    }
 
    // getting number of element larger than A[i] on Right.
    for (var i = n - 1; i >= 0; --i) {
        var cnt = 1;
 
        // get elements from stack until element greater
        // or equal to A[i] found
        while (s2.length!=0 && (s2[s2.length-1][0]) >= A[i]) {
            cnt += s2[s2.length-1][1];
            s2.pop();
        }
 
        s2.push([A[i], cnt]);
        right[i] = cnt;
    }
 
    var result = 0;
 
    // calculating required resultult
    for (var i = 0; i < n; ++i)
        result = (result + A[i] * left[i] * right[i]);
 
    return result;
}
 
// Driver program
 
var A = [3, 1, 2, 4];
var n = A.length;
 
// function call to get required resultult
document.write( sumSubarrayMins(A, n));
 
 
</script>
Output: 



17

 

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

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with industry experts, please refer DSA Live Classes




My Personal Notes arrow_drop_up
Recommended Articles
Page :