"Two adjacent windows over an array share almost all their elements. Recomputing each from scratch throws that overlap away. A sliding window keeps it — and that's the whole O(n²) → O(n) win."
The Wasteful Way, and the Fix
Say you want the maximum sum of any k consecutive elements. The naive approach: for each starting position, add up its k elements. That's n windows × k additions = O(n·k), which is O(n²) when k grows with n. But look at two neighboring windows — they overlap in all but one element on each side. The brute force re-adds that shared middle every single time.
The sliding window fixes this: compute the first window's sum once, then slide by adding the element entering on the right and subtracting the element leaving on the left. Each slide is O(1), so the whole scan is O(n). You never recompute the overlap — you just adjust at the edges. It's the same instinct as amortized analysis and prefix sums: don't redo work you already did.
Two Flavors of Window
- Fixed-size window — the window is always
kwide; it just slides. Used for "max/min/average of every k-length run." - Variable-size window — expand and shrink while a predicate changes monotonically. Longest-unique-substring fits. The minimum subarray with sum ≥ target needs nonnegative elements for this simple sum window; negative values break the monotonicity. Under the right premise, both pointers move forward only, for O(n) total work.
Why the Variable Window Is Still O(n)
The variable window looks like a nested loop — an outer pointer and an inner shrink loop — so people assume O(n²). The trick is that the left pointer never moves backward. Across the whole run, the right pointer advances n times and the left pointer advances at most n times. Total moves ≤ 2n. Counting total pointer movement rather than nesting is how you see it's O(n). This is the same amortized reasoning from the Complexity track, applied to a loop shape.