Your country

Tools that support it use your country for local currency, number formats, units and paper size. Your choice is saved only in this browser.

Type a name or a two-letter code. Use the up and down arrow keys to move through the countries, Enter to choose one and Escape to close.

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.

  • Intermediate
  • 30 minutes
  • Examples run with Python 3.14.8, Pyodide 314.0.7, Node.js 24.21.0, quickjs 0.32.0, Java 25, Clang 21.0.0 and Go 1.27.1
  • By MySmartCoPilot
Free intro, Pro: 8 of 30 minutes free
Free: The problem: the hottest day of every week · The brute force: rescan every window. With a pass: the other 10 sections and 3 interview answers, about 22 minutes.

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] to temps[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

Every window rescanned, with the comparisons counted Python · brute/window_brute.py
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

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.

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

Related tools

Report a problem with this lesson

Quick answers and tool search

Type to search tools or to get a quick answer, for example 18% of 2500. Use the up and down arrow keys to move through the results, Enter to choose, and Escape to close.