Field manual
Sliding window (variable)
O(n)Grow the window on the right; when it breaks the condition, shrink it from the left. The two ends only ever move forward, so the whole scan is O(n).
Signals
longest/shortest contiguous subarray or substringsatisfying a condition (sum <= K, at most, without breaking a limit)at most K distinct, no repeated element, contains all of Xcontiguous span, not a subsequence
Template
function longestUnder(arr, limit) {
let left = 0;
let sum = 0;
let best = 0;
for (let right = 0; right < arr.length; right++) {
sum += arr[right];
while (sum > limit) {
sum -= arr[left];
left++;
}
best = Math.max(best, right - left + 1);
}
return best;
}Looks similar, isn't
- Two pointers (opposite ends): Opposite pointers start apart and converge to one pair on a sorted array. A window has both pointers moving the same direction and keeps a live span; it does not need sorted input.
- Prefix sums: Prefix sums answer many arbitrary range-sum queries after O(n) setup. A window makes one forward pass for the single best span; if values can be negative, the shrink step breaks and prefix sums / other tools take over.
n up to 1e5..1e6, one best contiguous span under a monotone condition -> O(n): each end advances at most n times.
Learn this pattern