Problem
Given an array of integers arr, find the sum of min(b), where b ranges over every (contiguous) subarray of arr. Since the answer may be large, return the answer modulo 10^9 + 7.
Examples
Example 1:
| |
Example 2:
| |
Solution
Method 1 - Monotonic Increasing Stack
How Can Monotonic Stack Be Applied to This Problem?
Consider the element 3 in the array:
| |
The nearest smaller elements to the left (NSL) and right (NSR) (OR previous less element (PLE) and next less element(NLE)) of 3 are 2 and 1, respectively. The distance between 3 and its NSL 2 is 4, and the distance between 3 and its NSR 1 is 3.
The distance between 3 and its NSL 2 is 4. The distance between 3 and its NSR 1 is 3.
How Many Subarrays with 3 Being Its Minimum Value?
The answer is 4*3.
| |
How Much the Element 3 Contributes to the Final Answer?
It is 3*(4*3).
Algorithm
- Denote by
left[i]the distance between elementA[i]and its NSL. - Denote by
right[i]the distance between elementA[i]and its NSR. - The final answer is,
sum(arr[i]*left[i]*right[i] )Here is the detailed approach:
- Monotonic Stack with Contribution Calculation:
- Use a monotonic stack to track previous and next smaller elements for each element.
- Compute how many subarrays in which each element is the minimum element.
- Maintain two arrays,
leftandright, whereleft[i]indicates the number of contiguous subarrays ending atarr[i]in whicharr[i]is the minimum, andright[i]indicates the number of contiguous subarrays starting atarr[i]in whicharr[i]is the minimum. - The product of
left[i]andright[i]gives the count of contexts wherearr[i]is the minimum.
- Sum Calculation:
- Calculate the sum of the contributions of all elements being the minimum in their respective subarrays and take modulo
10^9 + 7to handle large numbers.
- Calculate the sum of the contributions of all elements being the minimum in their respective subarrays and take modulo
We have already seen following problems:
- NSL - Nearest Smallest Element to Left of Every Element
- NSR - Nearest Smaller Element to Right of every element
We also used it in Largest Rectangle in Histogram.
Code
| |
| |
Complexity
- ⏰ Time complexity:
O(n)for traversing the entire array and handling stack operations. - 🧺 Space complexity:
O(n)for storing left, right, and the stack.
Method 2 - DP and Monotonic Stack
Using a monotonic increasing stack to store indices:
dp[i + 1]: Stores the sum of minimums of all subarrays ending witharr[i]dp[i + 1] = dp[prev + 1] + (i - prev) * arr[i], whereprevis the index of the previous smaller element, and as we are using monotonous increasing stackstack.peek()
For eg. for arr = [3, 1, 2, 4, 3], when i = 4, all subarrays end with arr[4] (which is 3):
[3][4, 3][2, 4, 3][1, 2, 4, 3][3, 1, 2, 4, 3]
Here, stack.peek() = 2 and arr[2] = 2.
For the first two subarrays [3] and [4, 3], the sum of minimum is (i - stack.peek()) * arr[i] = 6.
For the last three subarrays [2, 4, 3], [1, 2, 4, 3], [3, 1, 2, 4, 3], as they all contain a 2 which is less than 3, the sum of minimum is dp[stack.peek() + 1] = 4.
Thus, dp[i + 1] = 4 + 6 = 10.
Code
| |
| |
Complexity
- ⏰ Time complexity:
O(n)for iterating through the array and handling stack operations. - 🧺 Space complexity:
O(n)for storing the dp array and stack.