Data Structures & Algorithms (DSA) Module 8 – Stacks, queues and deques
Deques and the sliding-window maximum
Use a double-ended queue to find the maximum of every window of k values in one pass: an original weather problem and the brute force that fails at 10⁶ days.
What you will learn
- Use a double-ended queue for operations at both ends in O(1)
- Compute the maximum of every window of size k in O(n) with a monotonic deque
- Explain why the deque holds indexes rather than values
- Recognise the deque behind 0-1 breadth-first search
Before you start
What you’ll learn · Before you start
What you will learn
- Use a double-ended queue for operations at both ends in O(1)
- Compute the maximum of every window of size k in O(n) with a monotonic deque
- Explain why the deque holds indexes rather than values
- Recognise the deque behind 0-1 breadth-first search
Before you start
On this page
A deque, short for double-ended queue, lets you add and remove items at both ends, front and back, in O(1). Deques generalise both stacks and queues: use one end only and you have a stack, add at one end and remove at the other and you have a queue. Their best-known use is the sliding-window maximum: the largest value in every run of k consecutive values of a list. Rescanning each window costs O(nk); a deque that keeps only the values that can still win answers every window in O(n) for the whole list. This lesson states an original version of the problem, measures the brute force, and shows what to notice before writing the fast version.
The problem: the hottest day of every week
A weather station keeps the highest temperature of each of n days. For every window of k consecutive days, report the highest temperature in that window: n − k + 1 answers, from the window that starts on day 0 to the one that ends on the last day.
- Input: n whole numbers,
temps[0]totemps[n - 1], and a window size k, with 1 ≤ k ≤ n ≤ 10⁶ and −60 ≤temps[i]≤ 60. - Output: n − k + 1 numbers, the maxima of the windows
0..k-1,1..k, and so on. - Time limit: about two seconds.
For [30, 32, 31, 29, 35, 34, 28, 27] with k = 3 the answer is [32, 32, 35, 35, 35, 34]. A window of a single day
just repeats the log, and a window as long as the log gives one number, the highest temperature overall.
The brute force: rescan every window
def window_max_brute(values, k):
"""The maximum of every window of k consecutive values, rescanning each window. Returns them and the comparisons."""
out, comparisons = [], 0
for start in range(len(values) - k + 1):
best = values[start]
for x in values[start + 1 : start + k]:
comparisons += 1
best = max(best, x)
out.append(best)
return out, comparisons
temps = [30, 32, 31, 29, 35, 34, 28, 27]
print("k = 3:", window_max_brute(temps, 3)[0])
print("k = 1:", window_max_brute(temps, 1)[0])
print("k = 8:", window_max_brute(temps, 8)[0])
print()
print(f"{'n':>6} {'k':>6} {'comparisons':>12} {'(n - k + 1)(k - 1)':>20}")
for n, k in [(2_000, 10), (2_000, 500), (2_000, 1_000), (2_000, 1_990)]:
_, comparisons = window_max_brute(list(range(n)), k)
print(f"{n:>6,} {k:>6,} {comparisons:>12,} {(n - k + 1) * (k - 1):>20,}") Output
k = 3: [32, 32, 35, 35, 35, 34]
k = 1: [30, 32, 31, 29, 35, 34, 28, 27]
k = 8: [35]
n k comparisons (n - k + 1)(k - 1)
2,000 10 17,919 17,919
2,000 500 748,999 748,999
2,000 1,000 999,999 999,999
2,000 1,990 21,879 21,879
Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 window_brute.py
Runs on this device, in your browser. The first run downloads Python (about 13.5 MB), which is kept for the next runs.
Your run, in this browser
Each window costs k − 1 comparisons, so the whole log costs (n − k + 1)(k − 1), as the counts confirm. That is largest when k is about n/2, about n²/4: at n = 10⁶ and k = 5 × 10⁵, some 2.5 × 10¹¹ comparisons, hours of work in Python and minutes even in compiled code. A heap of the window’s values does better, O(n log k), but it still pays a logarithm for every day.
What to notice
A temperature that is older than another one in the window, and not higher, can never be the maximum of any later window: the newer one stays in every later window the older one is in, and is at least as hot. Throw such readings away, and the ones that remain fall from oldest to newest. New readings join at the newest end, and readings that leave the window leave from the oldest end, which is the shape of a deque. Deques are made for exactly this, and they are how the sliding-window maximum comes down to a single pass.
The deque of candidates, step by step Pro: opens with a Pro, Premium or Ultimate pass
In this part:
- Why the front is the window’s maximum, and why the pass is O(n), proved
- The same pass in five languages, with run records
- Equal values, and why the deque holds indexes
- Measured: slices, a heap and the deque on a million days
- Deques in the standard libraries, and their slow middle
- Variants: the minimum, a calm stretch, and 0-1 search
- Edge cases and common bugs
- Practice: the maximum of every window, with sample tests
- The maximum of every window, in one pass
- Interview questions
- In a log of a million daily temperatures, find the longest run of consecutive days whose highest and lowest temperatures differ by at most 5 degrees. Explain your method, why it is correct, and what it costs.
- A dashboard shows the highest request latency of the last 60 seconds and refreshes every second. Requests arrive at irregular times, up to 50,000 a second. Does the monotonic deque still work when the window is defined by time rather than by a count, and what changes?
- Moving between neighbouring cells of a 1,000 × 1,000 city grid costs 1, except between cells of a metro line, where it costs 0. Find the cheapest cost from one cell to another. Why can a deque replace Dijkstra's heap here, and what does that save?
- Key takeaways
1 diagram · 7 runnable examples (Build and run all three, C++, Go, Java, JavaScript, Python) · 1 exercise with sample tests · 3 interview answers · about 19 minutes
Opening this part with your pass…
This part opens with any MySmartCoPilot pass.
- Pro pass · 1 week₹79$2.99
- 30 days₹179$5.99
- 1 year₹1,699$45
One payment; a pass never renews. The price shown is the total you pay: no fees or charges are added at checkout.
Passes can’t be bought right now, so this part can’t be opened at the moment. The free part above stands on its own. If you have a pass, enter your licence key.
It also opens every other in-depth part in Learn and every Pro tool. Sales are final, except where the law gives you a right to withdraw, for example in the EU and the UK (refund policy).
References
- collections: deque objects (Python Software Foundation)
- heapq: Heap queue algorithm (Python Software Foundation)
- Class ArrayDeque (Java SE 25) (Oracle)
- Interface Deque (Java SE 25) (Oracle)
- std::deque (cppreference.com)
- The Go Programming Language Specification: Slice expressions (The Go Authors)
- ECMAScript 2026 Language Specification: Array.prototype.pop (Ecma International)
- deque (Dictionary of Algorithms and Data Structures) (National Institute of Standards and Technology (NIST))
Related tools
Report a problem with this lesson
Kept only in this browser. Your Learn progress