LeetCopilot Logo
LeetCopilot
LeetCode Pattern/Monotonic Stack & Queue/Monotonic Stack vs Sliding Window vs DP: When to Use Each Pattern

Monotonic Stack vs Sliding Window vs DP: When to Use Each Pattern

LeetCopilot Team
Dec 22, 2025
20 min read
Monotonic StackPattern RecognitionSliding WindowTwo PointersDynamic ProgrammingInterview Strategy
Build a decision framework to instantly recognize monotonic stack problems and distinguish them from sliding window, dynamic programming, and two pointers. Learn the keywords, problem structures, and 30-second recognition checklist.

You're in an interview. The problem mentions "maximum," "window," and "subarray." Your mind races: Is this sliding window? Monotonic stack? Dynamic programming?

This is the pattern recognition problem—and it's what separates those who solve problems in 5 minutes from those who struggle for 30. The patterns look similar on the surface, but choosing the wrong one wastes precious interview time.

This comprehensive guide will teach you the exact decision framework to recognize monotonic stack problems, distinguish them from similar patterns, and choose the right approach in under 30 seconds.

The Pattern Recognition Problem

Why Confusion Happens

Many algorithmic patterns share similar keywords:

"Maximum subarray" could be:

  • Kadane's Algorithm (max sum)
  • Sliding Window (max with constraint)
  • Monotonic Stack (max with structure)

"Window of size k" could be:

  • Sliding Window (variable condition)
  • Monotonic Queue (max/min in window)

"Count subarrays" could be:

  • Prefix Sum + Hash Map
  • Monotonic Stack (contribution technique)
  • Dynamic Programming

The Cost of Wrong Choice

Choosing the wrong pattern:

  • ❌ Wastes 10-15 minutes implementing wrong solution
  • ❌ Leads to TLE (Time Limit Exceeded) or WA (Wrong Answer)
  • ❌ Signals poor pattern recognition to interviewer
  • ❌ Creates stress and reduces confidence

Choosing the right pattern:

  • ✅ Solve in 5-10 minutes
  • ✅ Optimal time complexity
  • ✅ Demonstrates strong fundamentals
  • ✅ Leaves time for follow-ups

The 30-Second Decision Framework

Step 1: Identify the Core Question

What is the problem asking for?

code
┌─────────────────────────────────────────┐
│ "Find next greater/smaller element"     │ → Monotonic Stack
├─────────────────────────────────────────┤
│ "Largest rectangle / histogram"         │ → Monotonic Stack (Increasing)
├─────────────────────────────────────────┤
│ "Sliding window maximum/minimum"        │ → Monotonic Queue
├─────────────────────────────────────────┤
│ "Maximum/minimum subarray sum"          │ → Kadane's / Prefix Sum
├─────────────────────────────────────────┤
│ "Longest substring with condition"      │ → Sliding Window
├─────────────────────────────────────────┤
│ "Count subarrays with sum = k"          │ → Prefix Sum + Hash Map
├─────────────────────────────────────────┤
│ "Optimal subsequence"                   │ → Dynamic Programming
└─────────────────────────────────────────┘

Step 2: Check for Monotonic Stack Keywords

🔍 Monotonic Stack Keywords:

  • "Next greater element"
  • "Next smaller element"
  • "Previous greater/smaller"
  • "Histogram"
  • "Largest rectangle"
  • "Stock span"
  • "Visible buildings"
  • "Trapping rain water"
  • "Remove K digits"

If you see these → 90% chance it's monotonic stack

Step 3: Distinguish from Similar Patterns

Use this decision tree:

code
Does the problem involve finding next/previous greater/smaller?
├─ YES → Monotonic Stack ✓
└─ NO → Continue

Does it involve a sliding window?
├─ YES → Is it asking for max/min in each window?
│   ├─ YES → Monotonic Queue ✓
│   └─ NO → Sliding Window (two pointers) ✓
└─ NO → Continue

Does it involve optimal sum/count?
├─ Sum of subarray = k → Prefix Sum + Hash Map ✓
├─ Maximum subarray sum → Kadane's Algorithm ✓
└─ Optimal subsequence → Dynamic Programming ✓

Monotonic Stack vs Sliding Window

Key Differences

AspectMonotonic StackSliding Window
GoalFind next/previous greater/smallerFind subarray with condition
WindowNo fixed windowFixed or variable window
StructureStack (LIFO)Two pointers
ComplexityO(n)O(n)
SpaceO(n)O(1) typically

When to Use Each

Use Monotonic Stack:

  • ✅ Finding next/previous greater/smaller element
  • Histogram or rectangle problems
  • Structure-based queries (what's the next larger bar?)

Use Sliding Window:

  • ✅ Finding longest/shortest subarray with condition
  • Contiguous elements must satisfy constraint
  • Expand/shrink window based on condition

Example Comparison

Problem 1: "Find next greater element for each position"

Wrong: Sliding Window

python
# Sliding window doesn't make sense here
# We're not looking for a contiguous subarray

Correct: Monotonic Stack

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

Problem 2: "Find longest subarray with sum ≤ k"

Wrong: Monotonic Stack

python
# Stack doesn't help with contiguous sum constraint

Correct: Sliding Window

python
left = 0
current_sum = 0
for right in range(n):
    current_sum += nums[right]
    while current_sum > k:
        current_sum -= nums[left]
        left += 1
    max_len = max(max_len, right - left + 1)

Hybrid: Sliding Window Maximum

Problem: "Find maximum in each sliding window of size k"

Why it's confusing: Has "sliding window" in the name but uses monotonic queue!

Analysis:

  • Sliding window aspect: Window of size k
  • Monotonic queue aspect: Need max/min in O(1)

Solution: Monotonic Queue (Deque)

python
from collections import deque
dq = deque()
for i in range(n):
    while dq and dq[0] < i - k + 1:
        dq.popleft()
    while dq and nums[i] > nums[dq[-1]]:
        dq.pop()
    dq.append(i)
    if i >= k - 1:
        result.append(nums[dq[0]])

Rule: If problem asks for max/min in each window, use monotonic queue, not sliding window two pointers.

Monotonic Stack vs Dynamic Programming

Key Differences

AspectMonotonic StackDynamic Programming
GoalFind next/previous extremesOptimal subsequence/subarray
RecurrenceNo recurrence relationHas recurrence relation
DependenciesIndependent elementsDepends on previous states
Typical UseNext greater, histogramLongest increasing subsequence

When to Use Each

Use Monotonic Stack:

  • ✅ Finding structural properties (next greater/smaller)
  • No optimal substructure needed
  • Linear scan with stack maintenance

Use Dynamic Programming:

  • Optimal substructure exists
  • Overlapping subproblems
  • ✅ Need to build solution from smaller problems

Example: Sum of Subarray Minimums

Problem: Find sum of minimums of all subarrays.

Naive DP: O(n²)

python
# dp[i] = sum of minimums of all subarrays ending at i
for i in range(n):
    min_val = nums[i]
    for j in range(i, -1, -1):
        min_val = min(min_val, nums[j])
        total += min_val
# Time: O(n²)

Optimized with Monotonic Stack: O(n)

python
# For each element, find how many subarrays it's the minimum
# Use contribution technique with monotonic stack
left, right = find_boundaries(nums)  # O(n) with stack
for i in range(n):
    count = (i - left[i]) * (right[i] - i)
    total += nums[i] * count
# Time: O(n)

Key insight: Monotonic stack optimizes certain DP problems by finding boundaries in O(n).

When Stack Optimizes DP

Pattern: When DP transition requires finding min/max in a range

Example problems:

  • Sum of Subarray Minimums (#907)
  • Sum of Subarray Ranges (#2104)
  • Constrained Subsequence Sum (#1425) - uses monotonic queue

Rule: If DP transition is O(k) and involves range min/max, consider monotonic stack/queue optimization.

Monotonic Stack vs Two Pointers

Key Differences

AspectMonotonic StackTwo Pointers
Array TypeAny arrayUsually sorted
GoalNext greater/smallerFind pairs/triplets
MovementStack push/popPointers move based on condition
SpaceO(n)O(1)

When to Use Each

Use Monotonic Stack:

  • Unsorted array
  • ✅ Finding next/previous greater/smaller
  • Structural queries

Use Two Pointers:

  • Sorted array (or can sort)
  • ✅ Finding pairs that meet condition
  • Opposite direction or same direction movement

Example: Container With Most Water

Problem: Find two lines that form container with maximum water.

Why it's confusing: Involves finding maximum, but uses two pointers!

Analysis:

  • Array is not sorted by height
  • But we can use greedy two pointers
  • Not about "next greater"—about optimal pair

Solution: Two Pointers (Opposite Direction)

python
left, right = 0, len(height) - 1
max_area = 0
while left < right:
    area = (right - left) * min(height[left], height[right])
    max_area = max(max_area, area)
    if height[left] < height[right]:
        left += 1
    else:
        right -= 1

Rule: If problem involves pairs and greedy decisions, consider two pointers even if array is unsorted.

Monotonic Stack vs Priority Queue

Key Differences

AspectMonotonic StackPriority Queue
ComplexityO(n)O(n log n) or O(n log k)
Use CaseNext greater/smallerGeneral min/max queries
OrderingMonotonic (strict)Heap property
RemovalLIFOMin/max element

When to Use Each

Use Monotonic Stack/Queue:

  • Next/previous greater/smaller
  • Sliding window max/min
  • ✅ Want O(n) complexity

Use Priority Queue:

  • K-th largest/smallest
  • Merge k sorted arrays
  • Median finding
  • ✅ Don't need optimal O(n)

Example: Sliding Window Maximum

Priority Queue: O(n log k)

python
import heapq
heap = []
for i in range(n):
    heapq.heappush(heap, (-nums[i], i))
    while heap[0][1] < i - k + 1:
        heapq.heappop(heap)
    if i >= k - 1:
        result.append(-heap[0][0])
# Time: O(n log k)

Monotonic Queue: O(n)

python
from collections import deque
dq = deque()
for i in range(n):
    while dq and dq[0] < i - k + 1:
        dq.popleft()
    while dq and nums[i] > nums[dq[-1]]:
        dq.pop()
    dq.append(i)
    if i >= k - 1:
        result.append(nums[dq[0]])
# Time: O(n)

Rule: For sliding window max/min, always use monotonic queue over priority queue.

See detailed comparison: Deque vs Priority Queue

Decision Tree: Complete Framework

code
┌─────────────────────────────────────────────────────────┐
│ STEP 1: What's the core question?                      │
└─────────────────────────────────────────────────────────┘
                        │
        ┌───────────────┼───────────────┐
        │               │               │
        v               v               v
  "Next greater"  "Max in window"  "Longest subarray"
        │               │               │
        v               v               v
  Monotonic Stack  Monotonic Queue  Sliding Window
        │               │               │
        └───────────────┴───────────────┘
                        │
                        v
┌─────────────────────────────────────────────────────────┐
│ STEP 2: Check array properties                         │
└─────────────────────────────────────────────────────────┘
                        │
        ┌───────────────┼───────────────┐
        │               │               │
        v               v               v
   Sorted?         Fixed window?    Need pairs?
        │               │               │
        v               v               v
  Two Pointers    Monotonic Queue  Two Pointers
        │               │               │
        └───────────────┴───────────────┘
                        │
                        v
┌─────────────────────────────────────────────────────────┐
│ STEP 3: Check for optimal substructure                 │
└─────────────────────────────────────────────────────────┘
                        │
        ┌───────────────┼───────────────┐
        │               │               │
        v               v               v
  Recurrence?      Sum = k?        Subsequence?
        │               │               │
        v               v               v
       DP        Prefix Sum + Hash     DP

Quick Recognition Checklist

✅ Use Monotonic Stack When You See:

  • "Next greater element"
  • "Next smaller element"
  • "Previous greater/smaller"
  • "Histogram"
  • "Largest rectangle"
  • "Stock span"
  • "Visible buildings"
  • "Trapping rain water"
  • "Remove K digits"
  • "Buildings with ocean view"

✅ Use Monotonic Queue When You See:

  • "Sliding window maximum"
  • "Sliding window minimum"
  • "Maximum in each window of size k"
  • "Constrained subsequence" (DP + queue)

✅ Use Sliding Window When You See:

  • "Longest substring with..."
  • "Shortest subarray with..."
  • "Maximum sum subarray with constraint"
  • "At most K distinct characters"
  • "Minimum window substring"

✅ Use Two Pointers When You See:

  • "Sorted array" + "find pairs"
  • "Two Sum II" (sorted)
  • "3Sum" (can sort)
  • "Container with most water"
  • "Trapping rain water" (can use two pointers OR stack)

✅ Use DP When You See:

  • "Longest increasing subsequence"
  • "Maximum profit" (stocks)
  • "Minimum cost"
  • "Count ways to..."
  • "Optimal subsequence"

✅ Use Prefix Sum When You See:

  • "Subarray sum equals k"
  • "Continuous subarray sum"
  • "Range sum query"

Common Misidentifications

Misidentification 1: Trapping Rain Water

Problem: Calculate water trapped between bars.

Confusion: Could be two pointers OR monotonic stack!

Both work:

Two Pointers: O(n) time, O(1) space

python
left, right = 0, len(height) - 1
left_max = right_max = water = 0
while left < right:
    if height[left] < height[right]:
        left_max = max(left_max, height[left])
        water += left_max - height[left]
        left += 1
    else:
        right_max = max(right_max, height[right])
        water += right_max - height[right]
        right -= 1

Monotonic Stack: O(n) time, O(n) space

python
stack = []
water = 0
for i in range(len(height)):
    while stack and height[i] > height[stack[-1]]:
        bottom = stack.pop()
        if not stack:
            break
        width = i - stack[-1] - 1
        bounded_height = min(height[i], height[stack[-1]]) - height[bottom]
        water += width * bounded_height
    stack.append(i)

Rule: When multiple patterns work, choose based on:

  • Space constraint (two pointers uses O(1))
  • Clarity (stack is more intuitive for some)
  • Interview context (demonstrate pattern knowledge)

Misidentification 2: Maximum Subarray Sum

Problem: Find maximum sum of contiguous subarray.

Confusion: Sliding window? DP? Monotonic stack?

Correct: Kadane's Algorithm (DP)

python
max_sum = current_sum = nums[0]
for num in nums[1:]:
    current_sum = max(num, current_sum + num)
    max_sum = max(max_sum, current_sum)

Why not sliding window? Window size is variable, but we're not maintaining a constraint—we're finding optimal sum.

Why not monotonic stack? Not about "next greater"—about optimal sum.

Misidentification 3: Longest Substring Without Repeating

Problem: Find longest substring without repeating characters.

Confusion: Monotonic stack? Two pointers?

Correct: Sliding Window (with hash set)

python
seen = set()
left = max_len = 0
for right in range(len(s)):
    while s[right] in seen:
        seen.remove(s[left])
        left += 1
    seen.add(s[right])
    max_len = max(max_len, right - left + 1)

Why not monotonic stack? Not about "next greater"—about longest valid window.

Practice: Pattern Recognition

Exercise 1: Identify the Pattern

For each problem, identify the correct pattern in 30 seconds:

Problem 1: "Given an array, for each element, find the next element that is greater than it."

Answer

Pattern: Monotonic Decreasing Stack
Keyword: "next element that is greater"
Time: O(n)

Problem 2: "Find the longest substring with at most K distinct characters."

Answer

Pattern: Sliding Window
Keyword: "longest substring with constraint"
Time: O(n)

Problem 3: "Find the maximum value in each sliding window of size K."

Answer

Pattern: Monotonic Queue (Deque)
Keyword: "maximum in each window"
Time: O(n)

Problem 4: "Count the number of subarrays with sum equal to K."

Answer

Pattern: Prefix Sum + Hash Map
Keyword: "count subarrays with sum"
Time: O(n)

Problem 5: "Find the largest rectangle in a histogram."

Answer

Pattern: Monotonic Increasing Stack
Keyword: "largest rectangle" + "histogram"
Time: O(n)

Problem 6: "Given a sorted array, find two numbers that sum to target."

Answer

Pattern: Two Pointers (Opposite Direction)
Keyword: "sorted array" + "find two numbers"
Time: O(n)

Problem 7: "Find the longest increasing subsequence."

Answer

Pattern: Dynamic Programming (or DP + Binary Search)
Keyword: "longest increasing subsequence"
Time: O(n²) or O(n log n)

Problem 8: "Calculate the sum of minimums of all subarrays."

Answer

Pattern: Monotonic Increasing Stack (Contribution Technique)
Keyword: "sum of minimums" + "all subarrays"
Time: O(n)

Problem 9: "Find the minimum window substring containing all characters."

Answer

Pattern: Sliding Window
Keyword: "minimum window" + "substring"
Time: O(n)

Problem 10: "Find the K-th largest element in an array."

Answer

Pattern: Priority Queue (Heap) or Quickselect
Keyword: "K-th largest"
Time: O(n log k) or O(n) average

Summary Table

Problem TypePatternTimeSpaceKeywords
Next greater/smallerMonotonic StackO(n)O(n)"next greater", "histogram"
Sliding window max/minMonotonic QueueO(n)O(k)"window maximum", "size k"
Longest substringSliding WindowO(n)O(1)"longest", "substring"
Find pairs (sorted)Two PointersO(n)O(1)"sorted", "two numbers"
Subarray sum = kPrefix Sum + HashO(n)O(n)"subarray sum", "equals k"
Optimal subsequenceDynamic ProgrammingO(n²)O(n)"longest", "subsequence"
K-th largestPriority QueueO(n log k)O(k)"K-th", "largest"

Conclusion

Pattern recognition is a learnable skill. With this decision framework, you can identify the correct pattern in under 30 seconds.

The 30-second checklist:

  1. Identify keywords: "next greater" → stack, "window max" → queue, "longest substring" → sliding window
  2. Check array properties: Sorted → two pointers, unsorted → stack/hash map
  3. Verify pattern fit: Does the template match the problem structure?

Key distinctions:

  • Monotonic Stack: Next/previous greater/smaller, histogram
  • Monotonic Queue: Sliding window max/min
  • Sliding Window: Longest/shortest substring with constraint
  • Two Pointers: Pairs in sorted array
  • DP: Optimal subsequence with recurrence

Practice strategy:

  1. Solve 3-5 problems from each pattern
  2. For each problem, identify pattern BEFORE coding
  3. Time yourself: can you identify in 30 seconds?
  4. Review misidentifications and understand why

Master pattern recognition, and you'll solve interview problems with confidence. For deep dives into specific patterns:

Next time you see a problem, ask: "What's the core question?" The answer will guide you to the right pattern.

Want to Practice LeetCode Smarter?

LeetCopilot is a free browser extension that enhances your LeetCode practice with AI-powered hints, personalized study notes, and realistic mock interviews — all designed to accelerate your coding interview preparation.

Also compatible with Edge, Brave, and Opera

Related Tutorials