Sum of minimum elements of all subarrays

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++

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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 

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 implementation of above approach 
  
# Function to return required minimum sum 
def sumSubarrayMins(A, n): 
  
    left, right = [None] * n, [None] *
      
    # 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

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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

chevron_right


Output:

17

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



My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.