Sum of Subarray Minimums (original) (raw)

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 Yourselfredirect icon

Table of Content

[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 #include using namespace std;

int sumSubMins(vector &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 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));

`

[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?

**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 #include #include using namespace std;

int sumSubMins(vector& 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 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));

`

[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 #include #include using namespace std;

int sumSubMins(vector& arr) { int n = arr.size(); vector dp(n, 0); vector right(n); vector 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 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 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 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.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));

`