Sum of Subarray Minimums

Last Updated : 4 Dec, 2025

Given an array arr[] of integers, find the sum of the minimum element of every possible subarray of array.

Examples: 

Input: arr[] = [10, 20] 
Output: 40
Explanation: Subarrays are [10], [20], [10, 20]. 
Minimums are [10, 20, 10]. Sum is 40.

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.

Try It Yourself
redirect icon

[Naive Approach] By Explore all Possible Subarrays - O(n2) Time and O(1) Space

The idea is to consider every possible subarray of the given array. For each subarray, we determine the minimum element and add it to our running sum. By doing this for all subarrays, the final result will be the sum of all minimum elements across all subarrays.

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 = {1, 2, 3, 4};
    cout << sumSubMins(arr) << endl;
    return 0;
}
Java
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 = {1, 2,3,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 = [1, 2,3,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 = {1, 2,3,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 = [ 1, 2, 3, 4 ];
console.log(sumSubMins(arr));

Output
20

[Expected Approach 1] Using Stack - O(n) Time and O(n) Space

Assume every element is the minimum element. So, each element has a range where it remains the minimum on both the left and the right side.
Now, the question transforms into: for every element, find the range where it will be the minimum.

How to find the range?

  • If we keep expanding to the left while the current element is still the minimum, as soon as we encounter an element smaller than the current one, that marks the boundary of its left range.
  • Similarly, if we expand to the right, the moment we find a smaller element, that becomes the boundary of its right range.

How to Count Subarrays in the Range?

Number of subarrays where A[i] is minimum= L × R

And its total contribution to the answer is:

Contribution of arr[i]= arr[i]× L× R

The idea is to find the range using Next Smaller and Previous Smaller elements (with the help of a monotonic stack) where the current element remains the minimum. Once the range is known, the contribution of that element to the total sum is calculated as arr[i] × L × R.

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<int> st;

    // distance to previous smaller element
    for (int i = 0; i < n; i++) {
        while (!st.empty() && arr[st.top()] > arr[i]) {
            st.pop();
        }
        left[i] = st.empty() ? (i + 1) : (i - st.top());
        st.push(i);
    }

    while (!st.empty()) st.pop();

    // distance to next smaller or equal element
    for (int i = n - 1; i >= 0; i--) {
        while (!st.empty() && arr[st.top()] >= arr[i]) {
            st.pop();
        }
        right[i] = st.empty() ? (n - i) : (st.top() - i);
        st.push(i);
    }

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

    return result;
}

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

class GfG {

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

        Stack<Integer> s1 = new Stack<>();
        Stack<Integer> s2 = new Stack<>();

        // Previous Smaller Element (strictly smaller)
        for (int i = 0; i < n; i++) {
            while (!s1.isEmpty() && arr[s1.peek()] > arr[i]) {
                s1.pop();
            }
            left[i] = s1.isEmpty() ? (i + 1) : (i - s1.peek());
            s1.push(i);
        }

        // Next Smaller Element (smaller or equal)
        for (int i = n - 1; i >= 0; i--) {
            while (!s2.isEmpty() && arr[s2.peek()] >= arr[i]) {
                s2.pop();
            }
            right[i] = s2.isEmpty() ? (n - i) : (s2.peek() - i);
            s2.push(i);
        }

        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 = {1, 2, 3, 4};
        System.out.println(sumSubMins(arr));  
    }
}
Python
def sumSubMins(arr):
    n = len(arr)
    left = [0] * n
    right = [0] * n

    s1 = []
    s2 = []

    # Previous Smaller Element (strictly smaller)
    for i in range(n):
        while s1 and arr[s1[-1]] > arr[i]:
            s1.pop()
        left[i] = (i + 1) if not s1 else (i - s1[-1])
        s1.append(i)

    # Next Smaller Element (smaller or equal)
    for i in range(n - 1, -1, -1):
        while s2 and arr[s2[-1]] >= arr[i]:
            s2.pop()
        right[i] = (n - i) if not s2 else (s2[-1] - i)
        s2.append(i)

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

    return result


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

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

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

        // Previous Smaller Element (strictly smaller)
        for (int i = 0; i < n; i++) {
            while (s1.Count > 0 && arr[s1.Peek()] > arr[i]) {
                s1.Pop();
            }
            left[i] = (s1.Count == 0) ? (i + 1) : (i - s1.Peek());
            s1.Push(i);
        }

        // Next Smaller Element (smaller or equal)
        for (int i = n - 1; i >= 0; i--) {
            while (s2.Count > 0 && arr[s2.Peek()] >= arr[i]) {
                s2.Pop();
            }
            right[i] = (s2.Count == 0) ? (n - i) : (s2.Peek() - i);
            s2.Push(i);
        }

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

        return result;
    }

    static void Main() {
        int[] arr = { 1, 2, 3, 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 = [];

    // Previous Smaller Element (strictly smaller)
    for (let i = 0; i < n; i++) {
        while (s1.length > 0 && arr[s1[s1.length - 1]] > arr[i]) {
            s1.pop();
        }
        left[i] = (s1.length === 0) ? (i + 1) : (i - s1[s1.length - 1]);
        s1.push(i);
    }

    // Next Smaller Element (smaller or equal)
    for (let i = n - 1; i >= 0; i--) {
        while (s2.length > 0 && arr[s2[s2.length - 1]] >= arr[i]) {
            s2.pop();
        }
        right[i] = (s2.length === 0) ? (n - i) : (s2[s2.length - 1] - i);
        s2.push(i);
    }

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

    return result;
}

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

Output
20

[Expected Approach 2] Using Dynamic Programming - O(n) Time and O(n) Space

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.

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> st;

    // 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 (!st.empty() && arr[i] < arr[st.back()]) {
            right[st.back()] = i;
            st.pop_back();
        }
        st.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 = {1,2,3,4};
    cout << sumSubMins(arr) << endl;  
    return 0;
}
Java
import java.util.Stack;
import java.util.Arrays;

class GfG {
    static int sumSubMins(int[] arr) {
        int n = arr.length;
        int[] dp = new int[n];
        int[] right = new int[n];
        Stack<Integer> st = 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 (!st.isEmpty() && arr[i] < arr[st.peek()]) {
                right[st.pop()] = i;
            }
            st.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 = {1, 2, 3, 4};
        System.out.println(sumSubMins(arr));  
    }
}
Python
def sumSubMins(arr):
    n = len(arr)
    dp = [0] * n
    right = [i for i in range(n)]
    st = []

    # Find index of next 
    # smaller element on the right
    for i in range(n):
        while st and arr[i] < arr[st[-1]]:
            right[st.pop()] = i
        st.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 = [1, 2, 3, 4]
    print(sumSubMins(arr))
C#
using System;
using System.Collections.Generic;

class GfG {
    static int sumSubMins(int[] arr) {
        int n = arr.Length;
        int[] dp = new int[n];
        int[] right = new int[n];
        Stack<int> st = 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 (st.Count > 0 && arr[i] < arr[st.Peek()]) {
                right[st.Pop()] = i;
            }
            st.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 = { 1, 2, 3, 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 st = [];

    // Find index of next 
    // smaller element on the right
    for (let i = 0; i < n; i++) {
        while (st.length > 0 && arr[i] < arr[st[st.length - 1]]) {
            right[st.pop()] = i;
        }
        st.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 = [1, 2, 3, 4];
console.log(sumSubMins(arr));

Output
20
Comment