Sum of Subarray Minimum Using Stack and Queue

0
68
Sum of Subarray Minimum

The Sum of Subarray Minimum problem is a well-known challenge in competitive programming and coding interviews. It requires finding the sum of the minimum elements of all subarrays in a given array.

A naive approach using brute force has a time complexity of O(n2)O(n^2), which is inefficient for large datasets. Instead, we can optimize the solution using Stack and Queue, reducing the complexity to O(n)O(n).

In this blog, we’ll explore the optimized approach to solve the Sum of Subarray Minimum problem using monotonic stacks and discuss the role of queues in handling similar problems efficiently.

Understanding the Problem Statement

Given an array arr[] of N integers, we need to find the sum of the minimum elements for all possible subarrays.

Example:

Input:

arr[] = [3, 1, 2, 4]

All subarrays and their minimums:

  • [3] → Min = 3
  • [1] → Min = 1
  • [2] → Min = 2
  • [4] → Min = 4
  • [3,1] → Min = 1
  • [1,2] → Min = 1
  • [2,4] → Min = 2
  • [3,1,2] → Min = 1
  • [1,2,4] → Min = 1
  • [3,1,2,4] → Min = 1

Sum of all minimums = 3 + 1 + 2 + 4 + 1 + 1 + 2 + 1 + 1 + 1 = 17

Constraints

  • 1≤N≤1051 \leq N \leq 10^5
  • 1≤arr[i]≤1061 \leq arr[i] \leq 10^6

A brute-force approach won’t work efficiently for large values of NN, so we need an optimized solution.

Sum of Subarray Minimum Using Stack and Queue Algorithm

Why Use Stack and Queue for Optimization?

To efficiently compute the sum of subarray minimums, we need a monotonic stack. This approach ensures:
âś… Efficient next smaller element and previous smaller element lookups.
âś… Reduction of time complexity to O(n)O(n) instead of O(n2)O(n^2).
âś… A stack-based traversal, avoiding unnecessary recalculations.

Queues, especially deque (double-ended queue), help in sliding window problems but are not the best fit for this exact problem.

Optimized Approach Using Monotonic Stack

The key idea is to determine the contribution of each element as the minimum in multiple subarrays using previous smaller elements (left boundary) and next smaller elements (right boundary).

Sum of Subarray Minimum Using Stack and Queue Algorithm

Steps to Solve Using Stack:

  1. Find the left boundary (Previous Less Element – PLE):
    • Using a monotonic increasing stack, determine how far left each element can be the minimum.
  2. Find the right boundary (Next Less Element – NLE):
    • Again, use a monotonic increasing stack to determine how far right each element can be the minimum.
  3. Calculate contribution:
    • Each element’s contribution to the total sum is determined as: arr[i]Ă—count of subarrays where arr[i] is the minimumarr[i] \times \text{count of subarrays where } arr[i] \text{ is the minimum}

Efficient Code Implementation in Python

def sumSubarrayMins(arr):
    MOD = 10**9 + 7
    n = len(arr)
    
    # Previous Less Element (PLE)
    ple = [-1] * n
    stack = []
    
    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)
    
    # Next Less Element (NLE)
    nle = [n] * n
    stack = []
    
    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 sum of minimums
    total_sum = 0
    for i in range(n):
        left = i - ple[i]
        right = nle[i] - i
        total_sum += (arr[i] * left * right) % MOD
    
    return total_sum % MOD

# Example usage
arr = [3, 1, 2, 4]
print(sumSubarrayMins(arr))  # Output: 17

Time Complexity Analysis

ApproachTime Complexity
Brute ForceO(n2)O(n^2)
Stack OptimizationO(n)O(n)

Since each element is pushed and popped from the stack at most once, the overall complexity is O(n)O(n), making it highly efficient.


Edge Cases Considered

✔ Single element array → [5] should return 5
✔ All elements same → [2,2,2] should handle duplicates correctly
✔ Decreasing order → [4,3,2,1] tests monotonic behavior
✔ Increasing order → [1,2,3,4] ensures correct right-boundary calculation

Sum of Subarray Minimum Using Stack and Queue Algorithm

Common Mistakes to Avoid

❌ Using > instead of >= in the Next Less Element stack check.
❌ Forgetting to consider modulo constraints for large outputs.
❌ Miscalculating left and right subarray contributions.

FAQs

How does the stack help optimize the Sum of Subarray Minimum?

The stack efficiently finds the previous and next smaller elements, reducing the time complexity to O(n)O(n) by avoiding nested loops.

Why do we use modulo 109+710^9+7?

To prevent integer overflow in large calculations, as required by constraints in coding competitions.

Can this be solved using a queue instead of a stack?

While queues are useful in sliding window problems, monotonic stacks are better suited for range-based calculations like this.

What happens if all elements are the same?

The algorithm correctly counts the subarrays and computes the sum, ensuring correctness for duplicate values.

How do I handle negative numbers?

This problem typically involves positive integers, but minor modifications (like handling absolute values) can extend it to negative numbers.

Conclusion

The Sum of Subarray Minimum problem can be efficiently solved using monotonic stacks. By finding the Previous Less Element (PLE) and Next Less Element (NLE), we reduce the complexity from O(n2)O(n^2) to O(n)O(n).

Understanding Stack and Queue concepts is crucial for solving range-based queries effectively in coding interviews and real-world applications.

Try implementing this approach in your next coding challenge!

LEAVE A REPLY

Please enter your comment!
Please enter your name here