A sliding window is a frame over a contiguous slice of an array or string. Instead of recomputing the answer for every possible slice from scratch (O(n^2) or worse), you slide the frame one element at a time: when the frame moves right you add one new element; when the frame moves left you remove one old element. Each element enters the window once and leaves once, so the whole scan costs O(n).
The window is the range between two pointers named left and right. A small piece of
state (a running sum, a count, a frequency map, a hash set) tracks whatever property
of the window you care about, so that “is the window valid?” is an O(1) check.
Reach for sliding window when the problem asks for one of these:
If the answer requires non-contiguous elements (subsequence, subset), sliding window is the wrong tool – look at Two Pointers, DP, or Backtracking instead.
The width is given (e.g. “size k”). Slide it end-to-end, update the running state on each slide, record the best.
window-size = k
initialize state for the first k elements
for right from k to n-1:
add element at right to state
remove element at right-k from state
update best answer from state
The width is not known in advance; the window grows and shrinks to satisfy a
constraint. The recipe below is the single most important block in this pattern –
memorise it. Every Medium/Hard problem in this section is just this template with a
more elaborate state and violates constraint check.
function variable-window(input, constraint):
left = 0
state = empty # sum, count, frequency map, etc.
best = identity # longest -> 0, shortest -> +infinity
for right from 0 to len(input)-1: # EXPAND
add input[right] to state
while state violates constraint: # SHRINK until valid again
remove input[left] from state
left = left + 1
update best using the current window [left..right]
return best
Two crucial details:
right pointer only moves forward; the while
loop pulls left forward as far as needed. Never move right backward.best AFTER the while-loop so you only ever measure a valid window.| Folder | LC | Problem | Difficulty | Teaches |
|---|---|---|---|---|
| 0121-best-time-to-buy-and-sell-stock | 121 | Best Time to Buy and Sell Stock | Easy | The simplest “running best” idea: one pass, track the minimum seen so far. |
| 0003-longest-substring-without-repeating-characters | 3 | Longest Substring Without Repeating Characters | Medium | Variable window with a hash map of last-seen indices. |
| 0424-longest-repeating-character-replacement | 424 | Longest Repeating Character Replacement | Medium | Window with a constraint on replacements; the int[26] frequency trick. |
| 0076-minimum-window-substring | 76 | Minimum Window Substring | Hard | Capstone: frequency map + a formed counter. Everything combined. |
| 0209-minimum-size-subarray-sum | 209 | Minimum Size Subarray Sum | Medium | Classic variable window: grow right to add, shrink left to remove. |
| 0219-contains-duplicate-ii | 219 | Contains Duplicate II | Easy | Fixed-distance window via a hash set that always holds the last k indices. |
The first and last are warm-ups; 0209 and 0003 drill the expand/shrink rhythm; 0424 and 0076 layer on richer state. By 0076 the template is muscle memory.
state when shrinking. Every element removed from the window
must decrement the sum, decrement its frequency count, or be removed from the set. A
window whose state is out of sync gives silently wrong answers.[left, right)
or [left..right] inclusive and compute the size accordingly (right - left vs
right - left + 1). The wrong formula is the #1 source of “answer off by one”.best inside the shrink loop. Always measure after the window is valid
again, or you will record windows that violate the constraint.best = 0 and use max; for
“shortest” initialise best = +infinity and use min. A surprising number of bugs are
just this.Five questions ramping from recall to design. Try each before revealing.
Q1 (recall). In the variable-size window template, which statement about the two pointers is always true?
left and right only ever move forwardleft moves forward but right can jump backwardleft can move backward to re-add dropped elementsQ2 (pattern recognition). New problem: “longest substring containing at most K distinct characters.” Which variant of this pattern fits?
right, shrink left while distinct > K, then record the lengthQ3 (pattern recognition). New problem: “is any value in the array repeated within k indices of an earlier equal value?” Which tool is the most direct?
k values, evicting the one that falls out of rangeQ4 (apply). Run the 0209 algorithm (shortest subarray, sum >= target) on target = 6, nums = [1, 2, 3, 4]. What is returned?
Q5 (design). In words, not code, sketch how to solve “longest substring with at most K distinct characters” using this pattern’s template.
Next: start with 0121-best-time-to-buy-and-sell-stock.