Given an array nums and a window size k, the window slides from the left to the right of the array, one position at a time, always covering k consecutive elements. Return an array of the maximum in each window position.
Input: nums = [1,3,-1,-3,5,3,6,7], k = 3 Output: [3,3,5,5,6,7] The maximum of each size-3 window as it slides across the array.
Input: nums = [1], k = 1 Output: [1] A single window containing 1.
- 1 <= nums.length <= 10^5 - -10^4 <= nums[i] <= 10^4 - 1 <= k <= nums.length
Recomputing each window's max from scratch is O(n·k). A monotonic deque of indices — kept decreasing by value — lets the window's maximum always sit at the front: you drop indices that have slid out of the window from the front, and drop smaller-or-equal values from the back. Each index enters and leaves once, so it's O(n).
“How many outputs are there?”
n - k + 1 — one maximum per window position.
“Does the deque hold values or indices?”
Indices — so you can tell when the front has slid out of the window.
I keep a deque of indices whose values decrease from front to back, so the front is always the current window's max.
Before recording, I drop the front if it's slid out of the window, and I drop smaller-or-equal values from the back when a new element arrives.
Once the window is full, the front element is the answer for that position.
Worked example — nums = [1, 3, -1, -3, 5, 3, 6, 7], k = 3
windows and their maxima: [1,3,-1]=3 [3,-1,-3]=3 [-1,-3,5]=5 [-3,5,3]=5 [5,3,6]=6 [3,6,7]=7 answer: [3, 3, 5, 5, 6, 7]
Because the deque is decreasing, its front is always the largest value among the indices still in the window.
Two cleanups keep the invariant: remove a front index that slid past the window, and remove back indices whose values are dominated by the incoming element.
Each index is added once and removed once across the whole scan, so despite the inner loop it's O(n).
| Max per window | Monotonic deque | |
|---|---|---|
| Idea | Scan each window for its max | Decreasing index deque; front is the max |
| Time | O(n * k) | O(n) |
| Space | O(1) | O(k) |
Full code is in the Approaches selector below.
Key takeaway
Keep a deque of indices decreasing by value. Pop the front when it slides out of the window; pop the back while it's <= the new element; push the index. Once the window is full, the front index's value is that window's maximum. O(n) time, O(k) space.
dq = deque()
for i in 0 .. n-1:
if dq and dq.front <= i - k: pop front
while dq and nums[dq.back] <= nums[i]: pop back
push i
if i >= k - 1: output nums[dq.front]