Sum of Subarray Minimums - Complete Solution Guide
Sum of Subarray Minimums is LeetCode problem 907, a Medium level challenge. This complete guide provides step-by-step explanations, multiple solution approaches, and optimized code in python3, java, cpp, c.
Problem Statement
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 . 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 is 17. Example 2: Input: arr = [11,81,94,43,3] Output: 444 Constraints: 1 <= arr.length <= 3 * 10 4 1 <= arr[i] <= 3 * 10 4
Detailed Explanation
The problem asks us to find the sum of the minimum elements of all contiguous subarrays within a given array `arr`. We need to consider every possible subarray, find the minimum value within each subarray, and then sum up all these minimum values. The final result should be returned modulo 10^9 + 7 to prevent integer overflow. For example, given `arr = [3, 1, 2, 4]`, the subarrays are `[3], [1], [2], [4], [3, 1], [1, 2], [2, 4], [3, 1, 2], [1, 2, 4], [3, 1, 2, 4]`. The minimums are `3, 1, 2, 4, 1, 1, 2, 1, 1, 1`, and their sum is `17`. The length of the input array is between 1 and 3 * 10^4, and each element's value is between 1 and 3 * 10^4.
Solution Approach
The provided solution uses a monotonic stack to determine, for each element in the array, the range of subarrays where that element is the minimum. The algorithm iterates through the array, maintaining a stack of indices that are strictly increasing (or non-decreasing) based on their corresponding values in the array. When a new element is encountered that is smaller than or equal to the element at the top of the stack, it means that the element at the top of the stack is no longer the minimum element for subarrays that extend further. The algorithm then pops the element from the stack and calculates the number of subarrays for which the popped element is the minimum. This count is then multiplied by the value of the popped element, and the result is added to the total sum. The process repeats until the stack is empty or the current element is greater than the top of the stack. After processing the element, its index is added to the stack. A sentinel value (0) is added to the end of the array to handle the remaining elements in the stack after iterating through the entire array.
Step-by-Step Algorithm
- Step 1: Initialize `MOD` to 10^9 + 7 and `total_sum` to 0. Create an empty stack to store indices.
- Step 2: Iterate through the array `arr` from `i = 0` to `n` (inclusive). If `i == n`, the `current_val` is set to 0 (sentinel value); otherwise, `current_val` is `arr[i]`.
- Step 3: While the stack is not empty and `current_val` is less than or equal to the element at the top of the stack (i.e., `arr[stack[-1]] >= current_val` in Python, `arr[stack.peek()] >= current_val` in Java/C++), pop the top index `mid_idx` from the stack.
- Step 4: Determine the left and right boundaries for the subarrays where `arr[mid_idx]` is the minimum. `left_boundary` is the index at the top of the stack (or -1 if the stack is empty), and `right_boundary` is the current index `i`.
- Step 5: Calculate the count of subarrays where `arr[mid_idx]` is the minimum: `count = (mid_idx - left_boundary) * (right_boundary - mid_idx)`.
- Step 6: Update `total_sum`: `total_sum = (total_sum + arr[mid_idx] * count) % MOD`.
- Step 7: Push the current index `i` onto the stack.
- Step 8: After the loop completes, return `total_sum`.
Key Insights
- Insight 1: The naive approach of generating all subarrays and finding their minimums would result in O(n^2) time complexity, which could be too slow for the given constraints. We need a more efficient approach.
- Insight 2: The key insight is to use a monotonic stack to efficiently determine the left and right boundaries where each element `arr[i]` is the minimum element of subarrays. This allows calculating the number of subarrays where `arr[i]` is the minimum in O(1) time.
- Insight 3: Using a stack to store indices helps keep track of the relative order and position of elements in the array, enabling the identification of boundaries efficiently.
Complexity Analysis
Time Complexity: O(n)
Space Complexity: O(n)
Topics
This problem involves: Array, Dynamic Programming, Stack, Monotonic Stack.
Companies
Asked at: Avito, Paytm, PhonePe, Sprinklr.