Sliding Window

Grow and shrink a window over the data instead of recomputing every range.

The idea

Sliding Window is what happens when you notice that two overlapping subarrays share almost all their work. Brute force recomputes each range from scratch; a window keeps a running summary (a sum, a count map, a max) and updates it in O(1) as one element enters and another leaves.

It's the highest-leverage pattern in interviews for one reason: an enormous class of "longest / shortest / count of substrings or subarrays satisfying X" questions collapse to the same dozen lines once you see the window.

How to recognize it

  • The answer is about a contiguous range โ€” substring, subarray โ€” never a subsequence (that's usually DP).
  • Words like "longest", "shortest", "at most K", "exactly K", "maximum sum of size k".
  • The brute force enumerates O(nยฒ) ranges and re-scans each one.
  • The validity of a window can be tracked incrementally โ€” adding or removing one element updates the state cheaply.

When to reach for it

  • Fixed-size windows: max/min/average of every k-length subarray โ€” slide and update.
  • Variable-size windows: grow the right edge greedily, shrink from the left only when the window breaks a constraint.
  • Frequency-map windows: anagram and "contains all characters of t" problems, where the state is a count map plus a satisfied-counter.
  • "At most K distinct / at most K replacements" problems, where the shrink condition is a budget.

The mental model

Write the loop the same way every time: for each right in 0..n, admit s[right] into the window state; then, while the window is invalid, evict s[left] and advance left; then record the answer from the current (valid) window. Grow eagerly, shrink lazily, measure when legal.

The crucial invariant: left never moves backward. Both pointers travel at most n steps across the whole run, which is why the nested-looking while inside a for is still O(n) โ€” amortize the shrinking over the run, not per iteration.

If shrinking can't restore validity incrementally โ€” if you'd have to rescan the window to know โ€” the window summary you chose is too weak. Strengthen the state (add a count map, a satisfied-counter, a monotonic deque) before abandoning the pattern.

O(n) time โ€” each element enters and leaves the window exactly once. Space is O(1) for numeric summaries or O(k) for a frequency map over the alphabet/window.

Where people get burned

  • Applying it to problems with negative numbers where "growing makes the sum bigger" stops being true โ€” the monotonic reasoning breaks (see Minimum Size Subarray Sum vs. its negative-number cousins).
  • Updating the answer before restoring validity โ€” decide whether you measure valid windows (usual) or after each admit, and be consistent.
  • Rebuilding the window state from scratch on shrink โ€” the whole point is the O(1) incremental update.
  • Confusing subsequence with substring in the problem statement, then wondering why the window never fits.

Practice progression

Knowing the pattern is half the job. Showing up daily is the other half.

DSAMotivator tracks this exact progression โ€” with streaks, XP, and a map that fills in as you go.

Start free โ€” 7 days