Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Chapter 188: Monotonic Queue/Deque Optimization

A monotonic deque maintains elements in monotonic (increasing or decreasing) order. It is the key to solving sliding window maximum/minimum in O(n) and optimizing certain DP transitions from O(n²) to O(n).


Sliding Window Maximum in O(n)

Given an array and window size k, find the maximum in every window.

vector<int> slidingMax(const vector<int>& a, int k) {
    deque<int> dq; // stores indices, values in decreasing order
    vector<int> result;
    for (int i = 0; i < (int)a.size(); i++) {
        // Remove elements outside the window
        while (!dq.empty() && dq.front() <= i - k) dq.pop_front();
        // Maintain decreasing order
        while (!dq.empty() && a[dq.back()] <= a[i]) dq.pop_back();
        dq.push_back(i);
        if (i >= k - 1) result.push_back(a[dq.front()]);
    }
    return result;
}

Complexity: O(n) time (each element pushed and popped at most once), O(k) space.


Walkthrough

Array: [3, 1, 4, 1, 5, 9, 2], k = 3.

ia[i]Deque (indices)Window max
03[0]
11[0, 1]
24[2]4
31[2, 3]4
45[4]5
59[5]9
62[5, 6]9

DP Optimization: Monotone Queue Convex Hull Trick

When a DP transition has the form:

``ndp[i] = min over j in [i-k, i-1] of (dp[j] + cost(j, i))```

and the cost satisfies a monotonicity condition on the optimal transition point, a monotonic deque maintains candidate indices. This reduces the inner loop from O(k) to O(1) amortized.

Typical structure:

for (int i = 1; i <= n; i++) {
    while (!dq.empty() && i - dq.front() > k) dq.pop_front();
    ndp[i] = dp[dq.front()] + cost(dq.front(), i);
    while (!dq.empty() && dp[dq.back()] >= dp[i]) dq.pop_back();
    dq.push_back(i);
}

Multi-Set Alternative

When monotonicity of the deque property doesn’t hold (arbitrary insertions and deletions), use a multiset (C++) or SortedDict (Python). Insertion and deletion are O(log n).


Common Mistakes

MistakeFix
Popping from wrong endMax deque: pop smaller from back, expired from front
Forgetting to check window boundsAlways pop front when index is out of range
Using monotonic queue for non-monotonic costsVerify the DP cost function satisfies the monotonicity requirement

Practice Problems

| # | Problem | Hint | |—|—| | 1 | Sliding Window Maximum (LeetCode 239) | Classic deque problem | | 2 | Shortest Subarray with Sum at Least K (LeetCode 862) | Monotonic deque on prefix sums | | 3 | Jump Game VI (LeetCode 1696) | DP + monotonic deque for max dp[j] in range | | 4 | Constrained Subsequence Sum (LeetCode 1425) | DP with deque, track max in last k | | 5 | Largest Subarray with Length K (variant) | Maintain deque of candidates | | 6 | Rectangle Area in Histogram | Use monotonic stack (variant) — same principle |


See Also