Free beta: 30 days of full access, no card needed.Sign up free

We use necessary cookies to run the site (sign-in and language). The contact and bug-report forms also use Google reCAPTCHA for spam protection, loaded only if you accept. Privacy policy

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