AW Dev Rethought

βœ‚οΈ Perfection is achieved not when there is nothing more to add, but when there is nothing left to take away - Antoine de Saint-ExupΓ©ry

🧩 Python DSA Patterns β€” Monotonic Stack & Queue πŸ“‰πŸ


Description:

Many array problems look hard not because of logic β€” but because of repeated comparisons.

Monotonic stacks and queues solve this by keeping elements in a specific order, allowing us to answer range and dominance questions efficiently.

This pattern turns several O(nΒ²) brute-force problems into clean O(n) solutions.


🧠 What Is a Monotonic Structure?

A monotonic stack or queue maintains elements in either:

  • Increasing order, or
  • Decreasing order

This ordering allows instant access to:

  • Next greater / smaller element
  • Previous greater / smaller element
  • Maximum / minimum in a sliding window

Each element is added once and removed once β€” guaranteeing linear time.


πŸ“ Next Greater Element (Monotonic Decreasing Stack)

We keep a stack of indices whose next greater element hasn’t been found yet.

def next_greater(nums):
    stack = []
    result = [-1] * len(nums)

    for i in range(len(nums)):
        while stack and nums[i] > nums[stack[-1]]:
            idx = stack.pop()
            result[idx] = nums[i]
        stack.append(i)

    print("Next Greater Elements:", result)

πŸ’‘ Why it works:

Once an element finds its next greater value, it never needs to be checked again.


πŸ“ Previous Smaller Element (Monotonic Increasing Stack)

Here, the stack maintains increasing order so the top always gives the previous smaller value.

def previous_smaller(nums):
    stack = []
    result = [-1] * len(nums)

    for i in range(len(nums)):
        while stack and nums[stack[-1]] >= nums[i]:
            stack.pop()
        result[i] = nums[stack[-1]] if stack else -1
        stack.append(i)

    print("Previous Smaller Elements:", result)

πŸ’‘ Key idea:

Elements that can never serve as a β€œprevious smaller” are removed early.


πŸ“ Daily Temperatures (Monotonic Stack)

For each day, find how many days it takes to encounter a warmer temperature.

def daily_temperatures(temps):
    stack = []
    result = [0] * len(temps)

    for i in range(len(temps)):
        while stack and temps[i] > temps[stack[-1]]:
            idx = stack.pop()
            result[idx] = i - idx
        stack.append(i)

    print("Days Until Warmer Temperature:", result)

πŸ’‘ Insight:

This is a direct application of Next Greater Element with distance tracking.


πŸ“ Sliding Window Maximum (Monotonic Queue)

A monotonic queue keeps the maximum element always at the front of the window.

from collections import deque

def sliding_window_max(nums, k):
    dq = deque()
    result = []

    for i in range(len(nums)):
        if dq and dq[0] == i - k:
            dq.popleft()

        while dq and nums[dq[-1]] < nums[i]:
            dq.pop()

        dq.append(i)

        if i >= k - 1:
            result.append(nums[dq[0]])

    print("Sliding Window Maximum:", result)

πŸ’‘ Why deque:

We need fast removals from both ends.


🧠 Where This Pattern Is Used

  • πŸ“Š Next / Previous Greater or Smaller problems
  • 🌑️ Daily Temperatures
  • πŸ“ˆ Stock Span
  • πŸͺŸ Sliding Window Maximum / Minimum
  • 🧱 Histogram & range dominance problems

Once learned, this pattern appears everywhere.


βœ… Takeaway

  • Monotonic stacks and queues enforce order
  • Each element is processed once β†’ O(n)
  • Store indices, not values
  • Choose:
    • Stack β†’ next/previous problems
    • Queue β†’ sliding window problems

This is one of the most high-impact patterns in DSA.


πŸ‹οΈ Practice Problems

  1. Next Greater Element I & II
  2. Daily Temperatures
  3. Stock Span
  4. Sliding Window Maximum
  5. Largest Rectangle in Histogram

πŸ“‚ Full Script

The blog covers the essentials β€” find the complete notebook with all snippets & extras on GitHub Repo πŸ‘‰ Python DSA Patterns


Link copied!

Comments

Add Your Comment

Comment Added!