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.
Table of Content
- [Naive Approach] By Explore all Possible Subarrays - O(n^2) Time and O(1) Space
- [Expected Approach 1] Using Stack - O(n) Time and O(n) Space
- [Expected Approach 2] Using Dynamic Programming - O(n) Time and O(n) Space
[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 ansif 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?
- 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 #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 resultif 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));
`