LeetCode Solutions
907. Sum of Subarray Minimums
Time: $O(n)$ Space: $O(n)$
class Solution {
public:
int sumSubarrayMins(vector<int>& arr) {
constexpr int kMod = 1'000'000'007;
const int n = arr.size();
long ans = 0;
// prev[i] := index k s.t. arr[k] is the prev min in arr[:i]
vector<int> prev(n, -1);
// next[i] := index k s.t. arr[k] is the next min in arr[i + 1:]
vector<int> next(n, n);
stack<int> stack;
for (int i = 0; i < n; ++i) {
while (!stack.empty() && arr[stack.top()] > arr[i]) {
const int index = stack.top();
stack.pop();
next[index] = i;
}
if (!stack.empty())
prev[i] = stack.top();
stack.push(i);
}
for (int i = 0; i < n; ++i) {
ans += static_cast<long>(arr[i]) * (i - prev[i]) * (next[i] - i);
ans %= kMod;
}
return ans;
}
};
class Solution {
public int sumSubarrayMins(int[] arr) {
final int kMod = 1_000_000_007;
final int n = arr.length;
long ans = 0;
// prev[i] := index k s.t. arr[k] is the prev min in arr[:i]
int[] prev = new int[n];
// next[i] := index k s.t. arr[k] is the next min in arr[i + 1:]
int[] next = new int[n];
Deque<Integer> stack = new ArrayDeque<>();
Arrays.fill(prev, -1);
Arrays.fill(next, n);
for (int i = 0; i < arr.length; ++i) {
while (!stack.isEmpty() && arr[stack.peek()] > arr[i]) {
final int index = stack.pop();
next[index] = i;
}
if (!stack.isEmpty())
prev[i] = stack.peek();
stack.push(i);
}
for (int i = 0; i < arr.length; ++i) {
ans += (long) arr[i] * (i - prev[i]) * (next[i] - i);
ans %= kMod;
}
return (int) ans;
}
}
class Solution:
def sumSubarrayMins(self, arr: List[int]) -> int:
kMod = 1_000_000_007
n = len(arr)
ans = 0
# prev[i] := index k s.t. arr[k] is the prev min in arr[:i]
prev = [-1] * n
# next[i] := index k s.t. arr[k] is the next min in arr[i + 1:]
next = [n] * n
stack = []
for i, a in enumerate(arr):
while stack and arr[stack[-1]] > a:
index = stack.pop()
next[index] = i
if stack:
prev[i] = stack[-1]
stack.append(i)
for i, a in enumerate(arr):
ans += a * (i - prev[i]) * (next[i] - i)
ans %= kMod
return ans