HomeBlog › Sliding Window Pattern

Sliding Window Pattern

One of the highest-frequency interview patterns. When to recognize it, a template that handles most variants, and three worked examples.

The sliding window pattern turns an O(n²) brute force over subarrays or substrings into O(n) by maintaining a moving range and updating it incrementally instead of recomputing from scratch. It's one of the most-asked patterns — especially at Meta and ByteDance — so recognizing it instantly is worth a lot.

When to recognize this pattern

The template

Most variable-size windows follow this shape: expand the right edge, and shrink the left edge while the window violates the constraint.

def sliding_window(s):
    left = 0
    window = {}              # state for the current window
    best = 0
    for right in range(len(s)):
        # 1. include s[right] in the window
        window[s[right]] = window.get(s[right], 0) + 1
        # 2. shrink from the left while the window is invalid
        while invalid(window):
            window[s[left]] -= 1
            left += 1
        # 3. record the answer for this valid window
        best = max(best, right - left + 1)
    return best

Worked examples

Longest substring without repeating characters

Problem: Find the length of the longest substring with all unique characters.

The window is invalid when a character repeats. Track each character's last index and jump left past it.

def lengthOfLongestSubstring(s):
    last = {}
    left = best = 0
    for right, ch in enumerate(s):
        if ch in last and last[ch] >= left:
            left = last[ch] + 1
        last[ch] = right
        best = max(best, right - left + 1)
    return best

O(n) time, O(min(n, charset)) space. The guard last[ch] >= left ensures you only move left for repeats inside the current window.

Maximum sum subarray of size k (fixed window)

Problem: Given an array and integer k, find the maximum sum of any contiguous subarray of size k.

Fixed-size window: add the new element, subtract the one that fell out, track the max.

def max_sum_k(nums, k):
    window = sum(nums[:k])
    best = window
    for right in range(k, len(nums)):
        window += nums[right] - nums[right - k]
        best = max(best, window)
    return best

O(n) time, O(1) space. No need to recompute the sum each step — that's the whole point of sliding.

Minimum window substring (hard)

Problem: Given strings s and t, return the smallest substring of s containing all characters of t.

Expand to make the window valid (contains all of t), then shrink to minimize while it stays valid.

from collections import Counter
def minWindow(s, t):
    need = Counter(t)
    missing = len(t)
    left = start = 0
    end = 0
    for right, ch in enumerate(s, 1):
        if need[ch] > 0: missing -= 1
        need[ch] -= 1
        if missing == 0:
            while need[s[left]] < 0:
                need[s[left]] += 1
                left += 1
            if end == 0 or right - left < end - start:
                start, end = left, right
    return s[start:end]

O(|s| + |t|) time. missing counts how many required characters are still unmatched; the inner while shrinks the window once it's valid.

Variations & pitfalls

Spot the pattern instantly with live AI support

CoPilot Interview surfaces the optimal pattern and a working solution with Big-O in about 4 seconds during real Zoom and Teams calls. Free for Windows and macOS, invisible on screen-share.

Download free

FAQ

When should I use the sliding window pattern?

When the problem involves a contiguous subarray or substring with a constraint - longest/shortest/max-sum with a size k, 'at most K distinct,' 'no repeats,' or a target sum. If a brute force would re-scan overlapping ranges, you can usually slide instead for O(n).

What's the difference between a fixed and variable sliding window?

A fixed window of size k adds the new element and removes the one that fell out each step. A variable window expands the right edge and shrinks the left edge with a while loop until the window satisfies (or stops satisfying) the constraint.

What's the time complexity of sliding window solutions?

Almost always O(n): each element enters the window once and leaves at most once, so the two pointers each traverse the array a single time. Space is O(1) or O(k) for the window state.

How do I handle 'exactly K' problems?

Use the at-most trick: exactly K equals atMost(K) minus atMost(K-1). Each at-most sub-problem is a standard sliding window, which is far easier than counting 'exactly' directly.

What's the most common sliding window mistake?

Updating the answer at the wrong time - either before the window is valid, or after over-shrinking. Always record the result at the precise point the window meets the constraint.