Skip to content
Coding Interviews

The Sliding Window Pattern Explained

By The EbookWale Team · Updated June 16, 2026 · 4 min read

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).

2 5 1 8 3 7 slide → window (size 3)
The window slides one step at a time — each element enters and leaves once.

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.

🔑 REMEMBER — The window's left pointer never goes backward. That's why the pattern is O(n) despite the nested-looking loop — every element is added once and removed at most once across the whole run.

The template

Most dynamic-window problems fit this shape:

  1. Expand right, adding arr[right] to the window state.
  2. While the window violates the constraint, shrink from left.
  3. 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.
⚠️ GOTCHA — Sliding window only works for contiguous subarrays/substrings. If the problem allows skipping elements (a subsequence), the window breaks — that's usually a dynamic programming problem instead.

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.