The Sliding Window Pattern Explained
The sliding window pattern solves subarray and substring problems in O(n) by moving a window across the data, expanding and shrinking it. Here's how it works, fixed vs dynamic windows, and when to use it.
The sliding window pattern solves subarray and substring problems by moving a window across the data and updating it incrementally, turning an O(n²) brute force into O(n). Instead of recomputing every possible subarray, you slide a range and adjust only what entered and left the window.
It’s one of the highest-value interview patterns because so many problems — “longest substring without repeating characters”, “maximum sum of size k”, “smallest subarray with sum ≥ target” — are sliding windows once you see it.
The core idea
A naive solution recomputes every subarray from scratch:
// Brute force: every window → O(n·k) or worse
for (let i = 0; i + k <= n; i++) {
let sum = 0;
for (let j = i; j < i + k; j++) sum += arr[j]; // recompute
}
The sliding window keeps a running value and only adjusts the edges as it moves — each element enters and leaves once, so it’s O(n).
Fixed window: constant size k
When the window size is fixed, add the new element and drop the one that fell off the left:
// Maximum sum of any k consecutive elements
let sum = 0, best = -Infinity;
for (let i = 0; i < arr.length; i++) {
sum += arr[i]; // expand right
if (i >= k) sum -= arr[i - k]; // shrink left — the window slid
if (i >= k - 1) best = Math.max(best, sum);
}
return best;
The window is always exactly k wide; it just glides one step at a time.
Dynamic window: grow and shrink on a condition
The more powerful form: expand the right edge greedily, and shrink the left edge whenever a constraint is violated.
// Longest substring with no repeating characters
function longestUnique(s) {
const seen = new Set();
let left = 0, best = 0;
for (let right = 0; right < s.length; right++) {
while (seen.has(s[right])) { // constraint broken → shrink
seen.delete(s[left]);
left++;
}
seen.add(s[right]); // expand
best = Math.max(best, right - left + 1);
}
return best;
}
The left pointer only ever moves forward, so even with the inner while, total work is O(n) — each character is added and removed at most once.
The template
Most dynamic-window problems fit this shape:
- Expand
right, addingarr[right]to the window state. - While the window violates the constraint, shrink from
left. - Record the answer (longest/shortest/count) for the current valid window.
The window’s “state” is usually a running sum, a count, or a hash map of character frequencies.
When to recognise it
Strong signals that a problem is a sliding window:
- A contiguous subarray or substring (not a subsequence).
- Words like longest, shortest, maximum, minimum, or “contains exactly/at most k”.
- A running quantity over the range — a sum, a count, a set, a frequency map.
If the elements don’t need to be contiguous, it’s probably not a sliding window — that’s often dynamic programming or two-pointer territory.
Common mistakes
- Shrinking from the wrong side — the left edge contracts; the right edge expands. Mixing them breaks the invariant.
- Recomputing the window each step instead of updating incrementally — that throws away the whole O(n) benefit.
- Wrong window-size bookkeeping — the current size is
right - left + 1; off-by-ones here are common. - Applying it to subsequence problems — sliding windows only work on contiguous ranges.
Where this fits
The sliding window is a Phase 3 pattern in the coding interview roadmap, closely related to the two-pointer technique (it is two pointers moving the same direction) and applied to arrays and strings.
The fixed and dynamic templates, with worked problems, are drawn out in our job-ready tier — JavaScript in Three Months, Python in Three Months, and Java in Three Months. For the advanced variants (windows with a monotonic deque, “at most k distinct” families) common in senior interviews, the for Staff Engineers tier goes deeper: JavaScript, Python, Java.
Spot “contiguous range + running constraint” and reach for the window.
Frequently asked questions
What is the sliding window pattern?
The sliding window pattern solves problems about a contiguous subarray or substring by maintaining a 'window' — a range defined by two pointers — and sliding it across the data. Instead of recomputing each subarray from scratch (O(n²)), you update the window incrementally as it moves, giving an O(n) solution.
What is the difference between a fixed and dynamic sliding window?
A fixed window has a constant size k and slides one element at a time (for example, the maximum sum of any k consecutive elements). A dynamic window grows and shrinks based on a condition (for example, the longest substring with no repeated characters), expanding the right edge and contracting the left when the condition breaks.
When should I use a sliding window?
Use it when a problem asks about a contiguous subarray or substring and some running quantity — a sum, a count, a set of characters, a maximum. Keywords like 'longest', 'shortest', 'maximum sum', or 'contains' over a contiguous range are strong signals.
What is the time complexity of the sliding window technique?
O(n). Although there are two nested-looking pointers, each element is added to the window once and removed at most once, so the total work is linear — far better than the O(n²) of recomputing every subarray.