Open In App

Sum of minimum elements of all subarrays

Last Updated : 09 Jul, 2025
Summarize
Comments
Improve
Suggest changes
Share
Like Article
Like
Report

Given an array arr[] of integers. The objective is to find the sum of minimum of all possible subarray of arr[].

Examples: 

Input: arr[] = [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 : arr[] = [1, 2, 3, 4] 
Output: 20
Explanation: Subarrays are [1], [2], [3], [4], [1, 2], [1, 2, 3], [1, 2, 3, 4], [2, 3], [2, 3, 4], [3, 4].
Minimums are 1, 2, 3, 4, 1, 1, 1, 2, 2, 3. Sum is 20.

[Naive Approach] Explore all Possible Subarrays

The idea behind this approach is to calculate the sum of the minimum elements of all possible subarrays in a brute-force manner.

For each starting index i in the array, we extend the subarray up to every index j ≥ i and keep track of the minimum element seen so far in that range. This running minimum, mini, represents the minimum value for the current subarray arr[i..j]. We then add this value to the total sum. By iterating over all such subarrays and accumulating their minimums, we obtain the final result. Though simple and intuitive, this method has a time complexity of O(n²), making it suitable only for small input sizes.

C++
#include <iostream>
#include <vector>
using namespace std;

int sumSubMins(vector<int> &arr) {
    int n = arr.size();  
    int ans = 0;  
    
    // finding out the all possible subarray
    for (int i = 0; i < n; i++) {
        int mini = arr[i]; 
        for (int j = i; j < n; j++) {
            
            // select the minimum in the subarray
            mini = min(mini, arr[j]);
            
            // Adding that minimum element 
            // of the subarray to the answer
            ans += mini;  
        }
    }
    return ans;
}

int main() {
    vector<int> arr = {3, 1, 2, 4};
    cout << sumSubMins(arr) << endl;
    return 0;
}
Java
class GfG {

    public static int sumSubMins(int[] arr) {
        int n = arr.length;
        int ans = 0;
        
        // finding out the all possible subarrays
        for (int i = 0; i < n; i++) {
            int mini = arr[i];
            for (int j = i; j < n; j++) {
                
                // select the minimum in the subarray
                mini = Math.min(mini, arr[j]);
                
                // Adding that minimum element 
                // of the subarray to the answer
                ans += mini;
            }
        }
        return ans;
    }

    public static void main(String[] args) {
        int[] arr = {3, 1, 2, 4};
        System.out.println(sumSubMins(arr)); 
    }
}
Python
def sumSubMins(arr):
    ans = 0
    n = len(arr)
    
    # finding out the all possible subarrays
    for i in range(n):
        mini = arr[i]
        for j in range(i, n):
            
            # select the minimum in the subarray
            mini = min(mini, arr[j])
            
            # Adding that minimum 
            # element of subarray to answer
            ans += mini
    return ans

if __name__ == "__main__":
    arr = [3, 1, 2, 4]
    print(sumSubMins(arr))
C#
using System;

class GfG {
    static int sumSubMins(int[] arr)
    {
        int n = arr.Length;  
        int ans = 0;
        
        // finding out the all possible subarrays
        for (int i = 0; i < n; i++) {
            int mini = arr[i];
            for (int j = i; j < n; j++) {
                
                // select the minimum in the subarray
                mini = Math.Min(mini, arr[j]);
                
                // Adding that minimum element 
                // of the subarray to the answer
                ans += mini;
            }
        }
        return ans;
    }

    public static void Main(string[] args)
    {
        int[] arr = { 3, 1, 2, 4 };
        Console.WriteLine(sumSubMins(arr));  
    }
}
JavaScript
function sumSubMins(arr) {
    let ans = 0;
    const n = arr.length;
    
    // finding out the all possible subarrays
    for (let i = 0; i < n; i++) {
        
        // To store the minimum element
        let mini = arr[i];
        for (let j = i; j < n; j++) {
            
            // Finding the minimum element of the subarray
            mini = Math.min(mini, arr[j]);
            
            // Adding that minimum element 
            // of the subarray to the answer
            ans += mini;
        }
    }
    return ans;
}

// Driver Code
const arr = [3, 1, 2, 4];
console.log(sumSubMins(arr));

Output-

17

Time Complexity: O(n2),because of two nested for loops 
Auxiliary Space: O(1)

[Expected Approach 1] Monotonic stack optimization

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.

Step by Step Approach:

The idea is to determine for each element arr[i], how many subarrays it is the minimum of, and then using that count to calculate its total contribution.
To do this efficiently:
For each element, we compute how far it can extend to the left and right while still being the minimum.

  • left[i] represents the number of consecutive elements to the left that are strictly greater than arr[i].
  • right[i] represents the number of consecutive elements to the right that are greater than or equal to arr[i].
    f(i) = left[i] × right[i]
    => The Contribution of arr[i] to the answer is arr[i]×left[i]×right[i]
C++
#include <iostream>
#include <vector>
#include <stack>
using namespace std;

int sumSubMins(vector<int>& arr) {
    int n = arr.size();
    vector<int> left(n), right(n);
    stack<pair<int, int>> s1, s2;

    // Count elements greater 
    // than arr[i] on the left
    for (int i = 0; i < n; ++i) {
        int cnt = 1;
        
        // get elements from stack until element 
        // greater to arr[i] found
        while (!s1.empty() && s1.top().first > arr[i]) {
            cnt += s1.top().second;
            s1.pop();
        }
        s1.push({arr[i], cnt});
        left[i] = cnt;
    }

    // Count elements greater than 
    // or equal to arr[i] on the right
    for (int i = n - 1; i >= 0; --i) {
        int cnt = 1;
        
        // get elements from stack until element 
        // greater or equal to arr[i] found
        while (!s2.empty() && s2.top().first >= arr[i]) {
            cnt += s2.top().second;
            s2.pop();
        }
        s2.push({arr[i], cnt});
        right[i] = cnt;
    }

    int result = 0;
    
    // calculating required result
    for (int i = 0; i < n; ++i)
        result += arr[i] * left[i] * right[i];

    return result;
}

int main() {
    vector<int> arr = {3, 1, 2, 4};
    cout << sumSubMins(arr) << endl; 
    return 0;
}
Java
import java.util.Stack;
import java.util.Arrays;

class GfG {

    public static int sumSubMins(int[] arr) {
        int n = arr.length;
        int[] left = new int[n];
        int[] right = new int[n];

        Stack<int[]> s1 = new Stack<>();
        Stack<int[]> s2 = new Stack<>();

        // Count elements greater 
        // than arr[i] on the left
        for (int i = 0; i < n; i++) {
            
            // get elements from stack until element 
           // greater to arr[i] found
            int count = 1;
            while (!s1.isEmpty() && s1.peek()[0] > arr[i]) {
                count += s1.pop()[1];
            }
            s1.push(new int[]{arr[i], count});
            left[i] = count;
        }

        // Count elements greater than 
        // or equal to arr[i] on the right
        for (int i = n - 1; i >= 0; i--) {
            
            // get elements from stack until element 
            // greater or equal to arr[i] found
            int count = 1;
            while (!s2.isEmpty() && s2.peek()[0] >= arr[i]) {
                count += s2.pop()[1];
            }
            s2.push(new int[]{arr[i], count});
            right[i] = count;
        }

        int result = 0;
        for (int i = 0; i < n; i++) {
            result += arr[i] * left[i] * right[i];
        }

        return result;
    }

    public static void main(String[] args) {
        int[] arr = {3, 1, 2, 4};
        System.out.println(sumSubMins(arr));  
    }
}
Python
def sumSubMins(arr):
    n = len(arr)
    left = [0] * n
    right = [0] * n

    s1 = []  
    s2 = []  

    # Count elements greater 
    # than arr[i] on the left
    for i in range(n):
        
        # get elements from stack until element 
        # greater to arr[i] found
        count = 1
        while s1 and s1[-1][0] > arr[i]:
            count += s1.pop()[1]
        s1.append((arr[i], count))
        left[i] = count

    # Count elements greater than 
    # or equal to arr[i] on the right
    for i in range(n - 1, -1, -1):
        
        # get elements from stack until element 
        # greater or equal to arr[i] found
        count = 1
        while s2 and s2[-1][0] >= arr[i]:
            count += s2.pop()[1]
        s2.append((arr[i], count))
        right[i] = count

    result = 0
    for i in range(n):
        result += arr[i] * left[i] * right[i]

    return result

if __name__ == "__main__":
    arr = [3, 1, 2, 4]
    print(sumSubMins(arr))  
C#
using System;
using System.Collections.Generic;

class GfG {
    public static int sumSubMins(int[] arr) {
        int n = arr.Length;
        int[] left = new int[n];
        int[] right = new int[n];

        Stack<(int val, int count)> s1 =
                            new Stack<(int, int)>();
        Stack<(int val, int count)> s2 =
                            new Stack<(int, int)>();

        // Count elements greater 
        // than arr[i] on the left
        for (int i = 0; i < n; i++)
        {
            int count = 1;
            while (s1.Count > 0 && s1.Peek().val > arr[i])
            {
                count += s1.Pop().count;
            }
            s1.Push((arr[i], count));
            left[i] = count;
        }

        // Count elements greater than 
        // or equal to arr[i] on the right
        for (int i = n - 1; i >= 0; i--)
        {
            int count = 1;
            while (s2.Count > 0 && s2.Peek().val >= arr[i])
            {
                count += s2.Pop().count;
            }
            s2.Push((arr[i], count));
            right[i] = count;
        }

        int result = 0;
        for (int i = 0; i < n; i++)
        {
            result += arr[i] * left[i] * right[i];
        }

        return result;
    }

    static void Main()
    {
        int[] arr = { 3, 1, 2, 4 };
        Console.WriteLine(sumSubMins(arr)); 
    }
}
JavaScript
function sumSubMins(arr) {
    const n = arr.length;
    const left = new Array(n).fill(0);
    const right = new Array(n).fill(0);

    const s1 = []; 
    const s2 = []; 

    // Count elements greater 
    // than arr[i] on the left
    for (let i = 0; i < n; i++) {
        
        // get elements from stack until element 
        // greater to arr[i] found
        let count = 1;
        while (s1.length > 0 && s1[s1.length - 1][0] > arr[i]) {
            count += s1.pop()[1];
        }
        s1.push([arr[i], count]);
        left[i] = count;
    }

    // Count elements greater than 
    // or equal to arr[i] on the right
    for (let i = n - 1; i >= 0; i--) {
        
        // get elements from stack until element 
        // greater or equal to arr[i] found
        let count = 1;
        while (s2.length > 0 && s2[s2.length - 1][0] >= arr[i]) {
            count += s2.pop()[1];
        }
        s2.push([arr[i], count]);
        right[i] = count;
    }

    let result = 0;
    for (let i = 0; i < n; i++) {
        result += arr[i] * left[i] * right[i];
    }

    return result;
}

// Driver code
const arr = [3, 1, 2, 4];
console.log(sumSubMins(arr)); 

Output
17

Time Complexity: O(n)
Auxiliary Space: O(n)

[Expected Approach 2] Dynamic Programming Approach

The idea is to compute the index of the next smaller element to the right for each element using a monotonic stack (increasing stack). This helps us determine how far the current element remains the minimum in subarrays starting from its index.

Step By Step Implementations:

  • Initialize dp[] of size n to store the total sum of subarrays starting at each index where the first element is the minimum.
  • Initialize right[] to store the index of the next smaller element to the right for each element.
  • Use a monotonic increasing stack to fill right[].
  • For each index i from 0 to n - 1, update right[stack.top()] = i while the stack is not empty and arr[i] < arr[stack.top()].
  • Set dp[n - 1] = arr[n - 1] as the base case.
  • Iterate from index n - 2 to 0.
  • If no smaller element exists to the right, set dp[i] = (n - i) * arr[i].
  • If a smaller element exists at index r = right[i], set dp[i] = (r - i) * arr[i] + dp[r].
  • Return the sum of all values in dp[] as the final result.
C++
#include <iostream>
#include <vector>
#include <numeric>
using namespace std;

int sumSubMins(vector<int>& arr) {
    int n = arr.size();
    vector<int> dp(n, 0);
    vector<int> right(n);
    vector<int> stack;

    // Initialize right[] to self indices
    for (int i = 0; i < n; i++) right[i] = i;

    // Find index of next 
    // smaller element on the right
    for (int i = 0; i < n; i++) {
        while (!stack.empty() && arr[i] < arr[stack.back()]) {
            right[stack.back()] = i;
            stack.pop_back();
        }
        stack.push_back(i);
    }

    // Fill dp[] from right to left
    dp[n - 1] = arr[n - 1];
    for (int i = n - 2; i >= 0; i--) {
        int r = right[i];
        if (r == i) {
            dp[i] = (n - i) * arr[i];
        } else {
            dp[i] = (r - i) * arr[i] + dp[r];
        }
    }
    return accumulate(dp.begin(), dp.end(), 0);
}

int main() {
    vector<int> arr = {3, 1, 2, 4};
    cout << sumSubMins(arr) << endl;  
    return 0;
}
Java
import java.util.Stack;
import java.util.Arrays;

class GfG {
    public static int sumSubMins(int[] arr) {
        int n = arr.length;
        int[] dp = new int[n];
        int[] right = new int[n];
        Stack<Integer> stack = new Stack<>();

        // Initialize right[] to self indices
        for (int i = 0; i < n; i++) right[i] = i;

        // Find index of next smaller
        // element on the right
        for (int i = 0; i < n; i++) {
            while (!stack.isEmpty() && arr[i] < arr[stack.peek()]) {
                right[stack.pop()] = i;
            }
            stack.push(i);
        }

        // Fill dp[] from right to left
        dp[n - 1] = arr[n - 1];
        for (int i = n - 2; i >= 0; i--) {
            int r = right[i];
            if (r == i) {
                dp[i] = (n - i) * arr[i];
            } else {
                dp[i] = (r - i) * arr[i] + dp[r];
            }
        }

        int sum = 0;
        for (int val : dp) sum += val;
        return sum;
    }

    public static void main(String[] args) {
        int[] arr = {3, 1, 2, 4};
        System.out.println(sumSubMins(arr));  
    }
}
Python
def sumSubMins(arr):
    n = len(arr)
    dp = [0] * n
    right = [i for i in range(n)]
    stack = []

    # Find index of next 
    # smaller element on the right
    for i in range(n):
        while stack and arr[i] < arr[stack[-1]]:
            right[stack.pop()] = i
        stack.append(i)

    # Fill dp[] from right to left
    dp[n - 1] = arr[n - 1]
    for i in range(n - 2, -1, -1):
        r = right[i]
        if r == i:
            dp[i] = (n - i) * arr[i]
        else:
            dp[i] = (r - i) * arr[i] + dp[r]

    return sum(dp)


if __name__ == "__main__":
    arr = [3, 1, 2, 4]
    print(sumSubMins(arr))  
C#
using System;
using System.Collections.Generic;

class GfG {
    public static int sumSubMins(int[] arr) {
        int n = arr.Length;
        int[] dp = new int[n];
        int[] right = new int[n];
        Stack<int> stack = new Stack<int>();

        // Initialize right[] to self indices
        for (int i = 0; i < n; i++) right[i] = i;

        // Find index of next 
        // smaller element on the right
        for (int i = 0; i < n; i++)
        {
            while (stack.Count > 0 && arr[i] < arr[stack.Peek()])
            {
                right[stack.Pop()] = i;
            }
            stack.Push(i);
        }

        // Fill dp[] from right to left
        dp[n - 1] = arr[n - 1];
        for (int i = n - 2; i >= 0; i--)
        {
            int r = right[i];
            if (r == i)
            {
                dp[i] = (n - i) * arr[i];
            }
            else
            {
                dp[i] = (r - i) * arr[i] + dp[r];
            }
        }

        int sum = 0;
        foreach (int val in dp) sum += val;
        return sum;
    }

    static void Main()
    {
        int[] arr = { 3, 1, 2, 4 };
        Console.WriteLine(sumSubMins(arr));  
    }
}
JavaScript
function sumSubMins(arr) {
    const n = arr.length;
    const dp = new Array(n).fill(0);
    const right = Array.from({ length: n }, (_, i) => i);
    const stack = [];

    // Find index of next 
    // smaller element on the right
    for (let i = 0; i < n; i++) {
        while (stack.length > 0 && arr[i] <
                    arr[stack[stack.length - 1]]) {
            right[stack.pop()] = i;
        }
        stack.push(i);
    }

    // Fill dp[] from right to left
    dp[n - 1] = arr[n - 1];
    for (let i = n - 2; i >= 0; i--) {
        const r = right[i];
        if (r === i) {
            dp[i] = (n - i) * arr[i];
        } else {
            dp[i] = (r - i) * arr[i] + dp[r];
        }
    }

    return dp.reduce((acc, val) => acc + val, 0);
}

// Driver code
const arr = [3, 1, 2, 4];
console.log(sumSubMins(arr));  

Output
17

Time Complexity: O(n) stack-based boundary finding, DP construction, and sum runs in linear time relative to the array size n
Auxiliary Space: O(n)


Practice Tags :

Similar Reads