DSABeginner6 min readPart 4 of 16

Sliding Window

The sliding window technique turns O(n²) nested-loop problems into O(n) by keeping a window over the data and sliding it one step at a time. It is the go-to pattern for substring, subarray and consecutive-element problems.

Can you explain sliding window out loud?

I'm Alex. Read this, then I'll interview you on real problems and push on the parts you skip.

The idea in one pictureCore idea

Instead of recomputing each window from scratch, you update it: add the element that enters on the right, remove the one that leaves on the left. Each element enters and leaves once, so the whole scan is O(n).

Window of size 3 sliding right

sum = 8215132012345First window: add up the first k elements.sum = 8 − 2 + 1 = 7215132012345Slide: subtract the element leaving (red), add the oneentering (green).
WalkthroughEach slide costs O(1), no matter how big the window is.

Fixed-size windowPattern

The window size k is given. Slide a window of size k across the array and compute a result at each position.

Maximum sum of a subarray of size kTypeScript
function maxSumSubarray(nums: number[], k: number): number {
  let windowSum = 0;
  // First window
  for (let i = 0; i < k; i++) windowSum += nums[i];
  let maxSum = windowSum;
  // Slide window
  for (let i = k; i < nums.length; i++) {
    windowSum += nums[i] - nums[i - k];
    maxSum = Math.max(maxSum, windowSum);
  }
  return maxSum;
}
TimeO(n)SpaceO(1)

Variable-size windowPattern

Here the size changes. Expand the right edge until the window breaks the rule, then shrink the left edge until the rule holds again.

Longest substring without repeats: "abcabcbb"

"abc" is validabcabcbb01234567leftrightExpand right while every character is new."bca" is valid againabcabcbb01234567leftrightA second "a" arrives, so shrink from the left until the old "a" isgone.
Longest substring without repeating charactersTypeScript
function lengthOfLongestSubstring(s: string): number {
  const seen = new Set<string>();
  let left = 0, maxLen = 0;
  for (let right = 0; right < s.length; right++) {
    while (seen.has(s[right])) {
      seen.delete(s[left]);
      left++;
    }
    seen.add(s[right]);
    maxLen = Math.max(maxLen, right - left + 1);
  }
  return maxLen;
}
TimeO(n)SpaceO(min(n, alphabet size))
%%{init: {"look":"handDrawn","handDrawnSeed":7,"theme":"base","fontFamily":"Virgil, \"Segoe Print\", \"Comic Sans MS\", cursive","themeVariables":{"fontFamily":"Virgil, \"Segoe Print\", \"Comic Sans MS\", cursive","fontSize":"16px","primaryColor":"#fff4e6","primaryBorderColor":"#1e1e1e","primaryTextColor":"#1e1e1e","secondaryColor":"#e7f5ff","tertiaryColor":"#ebfbee","lineColor":"#1e1e1e","textColor":"#1e1e1e","mainBkg":"#fff4e6","nodeBorder":"#1e1e1e","clusterBkg":"#f8f9fa","edgeLabelBackground":"#ffffff","actorBkg":"#e7f5ff","actorBorder":"#1e1e1e","noteBkgColor":"#fff9db","noteBorderColor":"#1e1e1e"}}}%%
graph LR
  A["expand: right++<br/>add s[right]"] --> B{"window<br/>still valid?"}
  B -->|yes| C["record answer"]
  B -->|no| D["shrink: remove s[left]<br/>left++"]
  D --> B
  C --> A
  class A blue
  class B yellow
  class C green
  class D red
classDef orange fill:#ffd8a8,stroke:#1e1e1e,color:#1e1e1e
classDef blue fill:#a5d8ff,stroke:#1e1e1e,color:#1e1e1e
classDef green fill:#b2f2bb,stroke:#1e1e1e,color:#1e1e1e
classDef red fill:#ffc9c9,stroke:#1e1e1e,color:#1e1e1e
classDef violet fill:#d0bfff,stroke:#1e1e1e,color:#1e1e1e
classDef yellow fill:#ffec99,stroke:#1e1e1e,color:#1e1e1e
classDef grey fill:#e9ecef,stroke:#1e1e1e,color:#1e1e1e
DiagramThe loop behind every variable window.

When to use a sliding windowWhen to use

The problem is about a contiguous runA subarray or a substring, not any subset.
You want the longest, shortest, largest or smallest of something
The brute force is O(n²) or O(n³) with nested loops
There is a window ruleFor example, “at most k distinct characters”.

Common patterns

ProblemWindowWhat you track
Max / min sum of a subarray of size kFixedA running sum
Longest substring with at most k distinct charactersVariableCharacter counts; shrink when distinct > k
Minimum window substringVariableCounts of needed characters; shrink to minimise
Permutation in stringFixed (size of s1)Character frequencies to compare

Common mistakesPitfalls

Not updating the window state when slidingWhen an element leaves on the left, update your counts, sum or set too.
Mixing up expand and shrinkExpand right to grow the window; shrink left to make it valid again.
Forgetting the final windowThe last position may hold the answer, so check after the loop if needed.
Using it on non-contiguous problemsIf you are allowed to skip elements, a sliding window does not apply.
Off-by-one on the window sizeBoth ends are included, so the size is right − left + 1.

In the interviewIn the interview

Interviewers often push back on the nested loop. That sentence is the answer they are waiting for.

Frequently asked questionsFAQ

When should you use a sliding window?

Use it on contiguous subarray or substring problems where the constraint involves a sum, length, or distinct-count bound. The moving-pointer pattern removes repeated left-side work, converting O(n^2) brute force into a single O(n) pass with O(1) or O(k) extra space.

What is the difference between a fixed and a variable window?

A fixed window keeps a constant length and shifts one element at a time, while a variable window grows and shrinks both ends to satisfy a constraint like sum below a target. Both share the same right-pointer expansion and left-pointer shrink mechanics.

How do you track character counts in a sliding window string problem?

Use a frequency map or an integer array of size 26 or 128 for characters. Add the incoming right character and remove the outgoing left character on each move, then compare the counts to the constraint. This keeps the whole scan O(n) with O(1) space for bounded alphabets.

Now explain sliding window to me out loud

I'll give you interview problems and ask follow-ups, like a real interviewer.

Practice with Alex

Keep readingKeep reading

Ready to practice?

Reading is step one. Saying it out loud is step two.

Start a mock interview with Alex, get pushed on the parts you skip, and see your hiring signal right after.