Close Menu
    Code and Debug
    • Home
    • Our Courses
    • Blog
    • About Us
    • Contact Us
    Facebook X (Twitter) Instagram YouTube WhatsApp
    • Home
    • Our Courses
    • Blog
    • About Us
    • Contact Us
    Facebook Instagram YouTube LinkedIn WhatsApp
    Code and Debug – BlogCode and Debug – Blog
    Code and Debug – BlogCode and Debug – Blog
    Home»Data Structures & Algorithms»Sum of Subarray Minimums | Leetcode 907 | Stack Optimal Solution
    Data Structures & Algorithms

    Sum of Subarray Minimums | Leetcode 907 | Stack Optimal Solution

    codeanddebugBy codeanddebug19 August 2025No Comments4 Mins Read
    Share Facebook Twitter Pinterest LinkedIn Tumblr Reddit Telegram Email
    Featured image of a question to solve sum of subarray minimum
    Share
    Facebook Twitter LinkedIn Pinterest Email

    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 109 + 7.

    Here’s the [Problem Link] to begin with.

    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 * 104
    • 1 <= arr[i] <= 3 * 104
    Contents:
     [show]
    • Brute Force (Nested Loops)
      • Intuition and Approach
      • Code
      • Code Explanation
      • Time and Space Complexity
      • Conclusion
    • Optimal (Monotonic Stack with PLE/NLE)
      • Intuition
      • Detailed Approach
      • Code
      • Code Explanation
      • Time and Space Complexity
      • Conclusion
    • When to Use Which
    • Common Pitfalls and Tips

    Brute Force (Nested Loops)

    Intuition and Approach

    • Enumerate all subarrays starting at i and ending at j.
    • Maintain running minimum for the current subarray and add it to the total.
    • Take modulo each time to prevent overflow. This is simple and correct but not efficient for large n.

    Code

    class Solution:
        def sumSubarrayMins(self, arr: List[int]) -> int:
            total = 0
            n = len(arr)
            for i in range(0, n):
                mini = float("inf")
                for j in range(i, n):
                    # Update running minimum for subarray arr[i..j]
                    mini = min(mini, arr[j])
                    # Add current subarray's minimum
                    total = (total + mini) % (10**9 + 7)
            return total

    Code Explanation

    • For each starting index i, expand j to the right while tracking the current minimum mini.
    • Each step contributes the current mini to the answer.
    • Time grows quadratically due to all pairs (i, j).

    Time and Space Complexity

    • Precise: Time O(n^2), Space O(1).
    • Simplified: Quadratic time; fine for small arrays, slow for large ones.

    Conclusion

    A great baseline for understanding the task, but not scalable.


    Optimal (Monotonic Stack with PLE/NLE)

    Intuition

    View the sum as the sum of contributions of each element arr[i] as the minimum across all subarrays where it is the smallest. For any index i:

    • Determine how many subarrays choose arr[i] as their minimum.
    • Let ple[i] be the index of the Previous Less Element (strictly less) to the left of i; if none, use -1.
    • Let nle[i] be the index of the Next Less Element (less or equal) to the right of i; if none, use n.
    • Then the count of subarrays where arr[i] is minimum equals:
      • left = i − ple[i] choices for the left boundary
      • right = nle[i] − i choices for the right boundary
      • total subarrays contributed by i = left × right
    • Contribution of arr[i] = arr[i] × left × right.

    Why strict vs non-strict?

    • To avoid double-counting equal elements, define PLE with “>” and NLE with “>=”. This breaks ties consistently: the “next less or equal” on the right ensures only one of equal elements takes ownership of a subarray.

    Detailed Approach

    • Compute PLE using a strictly increasing stack from left to right:
      • While top > arr[i], pop.
      • ple[i] = top index if exists, else -1.
    • Compute NLE using a non-decreasing stack from right to left:
      • While top >= arr[i], pop.
      • nle[i] = top index if exists, else n.
    • Sum contributions: arr[i] × (i − ple[i]) × (nle[i] − i), mod 1e9+7.

    Code

    class Solution:
        def sumSubarrayMins(self, arr):
            MOD = 10**9 + 7
            n = len(arr)
            stack = []
            ple = [-1] * n  # Previous Less Element index
            nle = [n] * n   # Next Less Element index
    
            # Previous Less Element (strictly less)
            for i in range(n):
                while stack and arr[stack[-1]] > arr[i]:
                    stack.pop()
                ple[i] = stack[-1] if stack else -1
                stack.append(i)
    
            # Reset stack
            stack = []
    
            # Next Less Element (less or equal)
            for i in range(n - 1, -1, -1):
                while stack and arr[stack[-1]] >= arr[i]:
                    stack.pop()
                nle[i] = stack[-1] if stack else n
                stack.append(i)
    
            # Calculate result by contribution
            result = 0
            for i in range(n):
                left = i - ple[i]
                right = nle[i] - i
                result = (result + arr[i] * left * right) % MOD
    
            return result

    Code Explanation

    • The first pass builds PLE using a monotonic increasing stack (values strictly increasing by indices): popping when a strictly greater value is found ensures ple[i] holds the nearest smaller element.
    • The second pass builds NLE using a monotonic stack with “>=” popping to handle duplicates correctly and ensure a unique owner for tied values.
    • The final loop aggregates each element’s contribution under modulo.

    Time and Space Complexity

    • Precise: Time O(n) (each index pushed/popped at most once per pass), Space O(n) for stacks and arrays.
    • Simplified: Linear time and space; ideal for large inputs.

    Conclusion

    The monotonic stack solution transforms a quadratic enumeration into an elegant linear-time contribution sum. The choice of strict vs non-strict comparisons is crucial to avoid double-counting with duplicates.


    When to Use Which

    • Use the Brute Force method for learning and tiny inputs.
    • Use the Monotonic Stack (PLE/NLE) method for production-grade efficiency with O(n) time.

    Common Pitfalls and Tips

    • Be mindful of tie-breaking: use “>” for PLE and “>=” for NLE.
    • Always apply modulo at each accumulation to prevent overflow.
    • Test with duplicates-heavy arrays (e.g., “) to validate tie-handling.
    Join our Advance DSA COURSE

    For any changes to the article, kindly email at code@codeanddebug.in or contact us at +91-9712928220.

    Medium Stack and Queues
    Share. Facebook Twitter Pinterest LinkedIn Tumblr Email
    Previous Article0 – 1 Knapsack Problem | 5 DP Solutions in Python
    Next Article Asteroid Collision | Leetcode 735 | Optimal Stack Solution
    codeanddebug
    • Website

    Related Posts

    Data Structures & Algorithms

    Maximum Points You Can Obtain from Cards | Leetcode 1423

    20 August 2025
    Data Structures & Algorithms

    Number of Substrings Containing All Three Characters | Leetcode 1358 | Optimal Solution using Sliding Window

    20 August 2025
    Data Structures & Algorithms

    Count Number of Nice Subarrays | Leetcode 1248

    20 August 2025
    Add A Comment
    Leave A Reply Cancel Reply

    Categories
    • Data Structures & Algorithms (195)
      • Beginner (68)
      • Expert (45)
      • Intermediate (82)
    • Uncategorised (1)
    Recent Posts

    Maximum Points You Can Obtain from Cards | Leetcode 1423

    20 August 2025

    Number of Substrings Containing All Three Characters | Leetcode 1358 | Optimal Solution using Sliding Window

    20 August 2025

    Count Number of Nice Subarrays | Leetcode 1248

    20 August 2025

    Binary Subarrays With Sum | Leetcode 930 | Optimal Prefix/Sliding Window Trick

    20 August 2025

    Longest Repeating Character Replacement | Leetcode 424

    20 August 2025
    Facebook Instagram YouTube LinkedIn WhatsApp
    © 2025 Code and Debug. All rights reserved.

    Type above and press Enter to search. Press Esc to cancel.