Sliding window problems are usually easier than they first appear. The stress comes from managing state while the interval expands and contracts. Once you decide what the window means, the rest gets much calmer.
Step one: decide whether the window is fixed or variable
Fixed-size window
Use this when the question says things like:
- subarray of size
k - substring length exactly
k - maximum average over
kelements
The pattern is:
- Build the first window.
- Slide one step at a time.
- Remove the outgoing element and add the incoming one.
Variable-size window
Use this when the window grows until a condition breaks and then shrinks to restore validity.
This often appears in:
- longest substring without repeating characters
- minimum window covering a set
- smallest subarray with sum at least
k
The central question
Ask yourself:
What state lets me tell whether the current window is valid?
Possible answers include:
- Current sum
- Frequency map
- Count of distinct characters
- Number of satisfied requirements
If your state does not answer validity directly, the implementation gets messy fast.
Template for a variable window
left = 0
for right in range(len(items)):
add(items[right])
while window_is_invalid():
remove(items[left])
left += 1
update_answer()
This version works because every element enters the window once and leaves once. That gives linear time.
Example: longest substring without repeating characters
Maintain a frequency map and shrink while any character count exceeds 1.
from collections import defaultdict
def longest_unique(s):
counts = defaultdict(int)
left = 0
best = 0
for right, ch in enumerate(s):
counts[ch] += 1
while counts[ch] > 1:
counts[s[left]] -= 1
left += 1
best = max(best, right - left + 1)
return best
Common failure modes
Updating the answer in the wrong place
If the answer should only use valid windows, update it after the shrink loop, not before.
Forgetting what left represents
left should mark the start of the current valid window, not the last place you happened to inspect.
Using a map when a scalar would do
If the state is just a running sum, keep it simple. Extra bookkeeping can hide the real idea.
A reusable review pass
Before you submit:
- Confirm what makes the window valid.
- Confirm which event forces shrinking.
- Confirm when the answer is updated.
- Confirm the formula for window length:
right - left + 1.
That last line sounds basic, but it saves a surprising number of points.
Closing thought
Sliding window is not one trick. It is a small framework for keeping exactly enough state around a moving interval. Once you define the window well, the code becomes much more mechanical.