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

  1. Calculate Left Boundaries:

    • For each element at index i, find how many elements to the left are greater than or equal to arr[i].

    • Use a monotonic stack to find the nearest smaller element on the left.

    • left[i] represents the number of subarrays ending at i where arr[i] is the minimum.

  2. Calculate Right Boundaries:

    • For each element at index i, find how many elements to the right are strictly greater than arr[i].

    • Use a monotonic stack to find the nearest smaller element on the right.

    • right[i] represents the number of subarrays starting at i where arr[i] is the minimum.

  3. 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.

  4. 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++)

⚑ View Alternative Approaches with Code and Analysis

πŸ“Š 2️⃣ Single Pass Stack Approach

πŸ’‘ Algorithm Steps:

  1. Use single stack to process elements

  2. Calculate contribution while maintaining stack

  3. Handle boundary conditions efficiently

  4. Optimize space usage

πŸ“ Complexity Analysis:

  • Time: ⏱️ O(n)

  • Auxiliary Space: πŸ’Ύ O(n) - for stack

βœ… Why This Approach?

  • Single pass through array

  • Efficient stack operations

  • Reduced memory allocations

πŸ“Š 3️⃣ Monotonic Stack with Contribution

πŸ’‘ Algorithm Steps:

  1. Maintain strictly increasing stack

  2. Calculate contribution when popping elements

  3. Handle duplicate values correctly

  4. Optimize for memory usage

πŸ“ Complexity Analysis:

  • Time: ⏱️ O(n)

  • Auxiliary Space: πŸ’Ύ O(n) - for stack

βœ… Why This Approach?

  • Clean monotonic stack implementation

  • Handles duplicates efficiently

  • Optimal time complexity

πŸ“Š 4️⃣ Dynamic Programming Approach

πŸ’‘ Algorithm Steps:

  1. Use DP to track minimum contributions

  2. Calculate sum incrementally

  3. Optimize space with rolling arrays

  4. Handle edge cases efficiently

πŸ“ Complexity Analysis:

  • Time: ⏱️ O(n)

  • Auxiliary Space: πŸ’Ύ O(n) - for DP array and stack

βœ… Why This Approach?

  • Intuitive DP approach

  • Builds solution incrementally

  • Easy to understand and debug

πŸ†š πŸ” Comparison of Approaches

πŸš€ Approach

⏱️ Time Complexity

πŸ’Ύ Space Complexity

βœ… Pros

⚠️ Cons

πŸ” Two-Pass Stack

🟒 O(n)

🟑 O(n)

πŸš€ Clear logic, easy to debug

πŸ’Ύ Two passes through array

πŸ”Ί Single Pass Stack

🟒 O(n)

🟑 O(n)

πŸ”§ Optimal passes

πŸ’Ύ More complex implementation

⏰ Monotonic Stack

🟒 O(n)

🟑 O(n)

πŸš€ Clean implementation

πŸ”„ Requires careful duplicate handling

πŸ“Š Dynamic Programming

🟒 O(n)

🟑 O(n)

⚑ Intuitive approach

πŸ”§ Additional DP array needed

πŸ† Best Choice Recommendation

🎯 Scenario

πŸŽ–οΈ Recommended Approach

πŸ”₯ Performance Rating

⚑ Interview/Competitive Programming

πŸ₯‡ Two-Pass Stack

β˜…β˜…β˜…β˜…β˜…

πŸ“Š Production Code

πŸ₯ˆ Monotonic Stack

β˜…β˜…β˜…β˜…β˜†

🎯 Learning/Educational

πŸ₯‰ Dynamic Programming

β˜…β˜…β˜…β˜…β˜†

πŸš€ Memory Constrained

πŸ… Single Pass Stack

β˜…β˜…β˜…β˜…β˜…

πŸ§‘β€πŸ’» Code (Java)

🐍 Code (Python)

🧠 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

Visitor counter

Last updated