2Brute2Best
🔥0
06

Window + Monotonic Deque (Sliding Window Sub-pattern)

You need the max or min of the current window at every step. A deque keeps candidates in sorted order and throws away elements that can never be the answer again.

Signals in the problem statement
  • ›

    "maximum of every window"

  • ›

    "max − min ≤ limit"

  • ›

    best value among the last k positions

  • ›

    "shortest subarray with sum ≥ k" with negatives (prefix sums + deque)

What makes it different

A sum or count can be updated in O(1), but a max cannot (removing the max leaves you not knowing the next one). The deque fixes that.

Questions

ordered from “learn the idea” to “recognise it without help”
  1. 1
    Sliding Window Maximum
    Basic Anchor·LeetCode #239
    Hard
  2. 2Medium
  3. 3
    Maximum Number of Robots Within Budget
    Slight Variation·LeetCode #2398
    Hard
  4. 4
    Shortest Subarray with Sum at Least K
    Tricky / Edge Case·LeetCode #862
    Hard

Template

deque-template.cpp
// Maximum of every window of size k using a monotonic deque.
// dq holds indices; their values are in decreasing order front -> back.
vector<int> windowMax(vector<int>& a, int k) {
    deque<int> dq;
    vector<int> res;
    for (int right = 0; right < (int)a.size(); right++) {
        while (!dq.empty() && a[dq.back()] <= a[right]) dq.pop_back(); // can never be max again
        dq.push_back(right);
        if (dq.front() <= right - k) dq.pop_front();                 // fell out of the window
        if (right >= k - 1) res.push_back(a[dq.front()]);            // front = current max
    }
    return res;
}
Remember this · Sliding Window
Trigger
Contiguous subarray / substring + longest, shortest, maximum, count, or "of size K".
Think
Can I keep a valid range and move it, instead of checking every subarray from scratch?
Key question
When is my current window valid?