09. Sum of Subarray Minimums
β GFG solution to the Sum of Subarray Minimums problem: find the total sum of minimum elements in all subarrays using monotonic stack and contribution technique. π
The problem can be found at the following link: π Question Link
π§© Problem Description
Given an array arr[]
of positive integers, find the total sum of the minimum elements of every possible subarrays.
A subarray is a contiguous sequence of elements within an array. For each subarray, we need to find its minimum element and sum all these minimum values.
π Examples
Example 1
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 of all these is 17.
Example 2
Input: arr[] = [71, 55, 82, 55]
Output: 593
Explanation: The sum of the minimum of all the subarrays is 593.
π Constraints
$1 \le \text{arr.size()} \le 3 \times 10^4$
$1 \le \text{arr}[i] \le 10^3$
β
My Approach
The optimal approach uses Monotonic Stack with Contribution Technique to efficiently calculate how many times each element contributes as a minimum in different subarrays:
Two-Pass Stack
Calculate Left Boundaries:
For each element at index
i
, find how many elements to the left are greater than or equal toarr[i]
.Use a monotonic stack to find the nearest smaller element on the left.
left[i]
represents the number of subarrays ending ati
wherearr[i]
is the minimum.
Calculate Right Boundaries:
For each element at index
i
, find how many elements to the right are strictly greater thanarr[i]
.Use a monotonic stack to find the nearest smaller element on the right.
right[i]
represents the number of subarrays starting ati
wherearr[i]
is the minimum.
Calculate Contribution:
For each element
arr[i]
, its total contribution =arr[i] Γ left[i] Γ right[i]
.This gives the sum of
arr[i]
across all subarrays where it's the minimum.
Sum All Contributions:
Add up all individual contributions to get the final result.
π Time and Auxiliary Space Complexity
Expected Time Complexity: O(n), where n is the size of the array. Each element is pushed and popped from the stack at most once, resulting in linear time complexity.
Expected Auxiliary Space Complexity: O(n), as we use additional arrays for left and right boundaries and a stack for processing, all of which require O(n) space.
π§βπ» Code (C++)
class Solution {
public:
int sumSubMins(vector<int>& arr) {
const int MOD = 1e9 + 7;
int n = arr.size();
vector<int> left(n), right(n);
stack<int> st;
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();
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);
}
long long res = 0;
for (int i = 0; i < n; i++) {
res = (res + (long long)arr[i] * left[i] * right[i]) % MOD;
}
return res;
}
};
π§βπ» Code (Java)
class Solution {
public int sumSubMins(int[] arr) {
final int MOD = 1000000007;
int n = arr.length;
int[] left = new int[n];
int[] right = new int[n];
Deque<Integer> st = new ArrayDeque<>();
for (int i = 0; i < n; i++) {
while (!st.isEmpty() && arr[st.peekLast()] >= arr[i]) st.pollLast();
left[i] = st.isEmpty() ? i + 1 : i - st.peekLast();
st.offerLast(i);
}
st.clear();
for (int i = n - 1; i >= 0; i--) {
while (!st.isEmpty() && arr[st.peekLast()] > arr[i]) st.pollLast();
right[i] = st.isEmpty() ? n - i : st.peekLast() - i;
st.offerLast(i);
}
long res = 0;
for (int i = 0; i < n; i++) {
res = (res + (long) arr[i] * left[i] * right[i]) % MOD;
}
return (int) res;
}
}
π Code (Python)
class Solution:
def sumSubMins(self, arr):
MOD = 10**9 + 7
n = len(arr)
left = [0] * n
right = [0] * n
st = []
for i in range(n):
while st and arr[st[-1]] >= arr[i]:
st.pop()
left[i] = i + 1 if not st else i - st[-1]
st.append(i)
st.clear()
for i in range(n - 1, -1, -1):
while st and arr[st[-1]] > arr[i]:
st.pop()
right[i] = n - i if not st else st[-1] - i
st.append(i)
return sum(arr[i] * left[i] * right[i] for i in range(n)) % MOD
π§ Contribution and Support
For discussions, questions, or doubts related to this solution, feel free to connect on LinkedIn: π¬ Any Questions?. Let's make this learning journey more collaborative!
β If you find this helpful, please give this repository a star! β
πVisitor Count
Last updated