Sliding window is the first pattern worth learning properly because it shows up in the first round at almost every company, and because it is the cleanest example of turning a brute force into a linear scan. In the 370-problem set DSA Tracker curates, the topic itself has 8 problems, but the same idea hides inside a dozen more that are filed under Arrays and Strings.
The idea in one sentence
You are asked something about a contiguous range of an array or string. A brute force checks every start index and every end index, which is O(n^2) pairs. A sliding window keeps a single range alive, extends it one element at a time on the right, and shrinks it from the left only when it has to. Each element enters the window once and leaves once, so the whole scan is O(n).
The word to spot in the problem statement is contiguous. Subarray, substring, consecutive elements, "window of size k": all of these mean the answer is one unbroken range.
Template 1: the fixed window
The window always has exactly k elements. Every step you add nums[right] and remove nums[right - k].
def max_sum_of_size_k(nums, k):
window = sum(nums[:k])
best = window
for right in range(k, len(nums)):
window += nums[right] - nums[right - k]
best = max(best, window)
return best
Fixed windows answer questions of the form "for every range of size k, compute X and report the best". Typical wording: maximum sum subarray of size k, average of every k consecutive elements, first negative number in every window, count of anagrams of a pattern inside a text.
The only thing that changes between problems is what you maintain inside the window. A running sum is the simplest. For anagram counting you maintain a frequency map and a counter of "characters still needed". For maximum of every window you maintain a monotonic deque, which is the one fixed-window variant that is genuinely harder.
Template 2: the variable window
Here the window size is what you are solving for. You extend on the right unconditionally, and while the window is invalid you shrink from the left.
def longest_without_repeat(s):
last_seen = {}
left = 0
best = 0
for right, ch in enumerate(s):
if ch in last_seen and last_seen[ch] >= left:
left = last_seen[ch] + 1
last_seen[ch] = right
best = max(best, right - left + 1)
return best
That is Longest Substring Without Repeating Characters, the most asked sliding window problem on the internet. Notice the shape: a rule that decides whether the current window is valid, a left pointer that only moves forward, and a running best.
Variable windows come in two flavours and the shrink condition flips between them:
- Longest valid window. Shrink only while the window is invalid, record the length after each extension. Examples: longest substring with at most k distinct characters, longest subarray with sum at most s, longest ones after flipping at most k zeros.
- Shortest valid window. Shrink while the window is still valid to make it as small as possible, record the length before each shrink. Examples: minimum size subarray with sum at least s, minimum window substring.
If you find yourself stuck, ask which flavour you are in. Nine times out of ten the bug is a shrink loop with the condition inverted.
The 8 problems to solve
In rough order of difficulty:
- Maximum sum subarray of size k (fixed)
- Average of all subarrays of size k (fixed)
- Longest substring without repeating characters (variable, longest)
- Longest substring with at most k distinct characters (variable, longest)
- Minimum size subarray sum (variable, shortest)
- Permutation in string, also called anagram check (fixed, frequency map)
- Sliding window maximum (fixed, monotonic deque)
- Minimum window substring (variable, shortest, frequency map)
Solve the first five before you touch the last three. Problems 6 to 8 add a data structure inside the window; if the plain templates are not automatic yet, the extra structure will hide which part you are unsure about.
You can watch the pointers move step by step in the sliding window visualizer before writing any code. It uses the exact example from the problem statement, so what you see is what the judge will run.
Where it goes wrong in interviews
Forgetting that left only moves forward. If your left pointer can jump backwards, the O(n) guarantee is gone. In the longest-substring code above, the last_seen[ch] >= left check exists precisely to stop left from moving back to an occurrence that is already outside the window.
Recomputing the aggregate from scratch. Summing the window with sum(nums[left:right+1]) inside the loop is O(n) per step, so the whole thing is O(n^2) again. Maintain the aggregate incrementally.
Off-by-one on the window length. The length is right - left + 1. Write it once as a variable if you keep getting it wrong.
Not stating the pattern out loud. Interviewers give credit for "this is a variable sliding window, longest flavour, the invariant is at most k distinct" before a single line is written. Say it.
How this fits a role-based plan
Sliding window is core for every software engineering role, and it matters more than average for backend and data engineering interviews, where streaming and log-processing questions are natural framings for it. If you have set a target role in DSA Tracker, the topic is already ordered by how often it appears for that role; if not, the topic hub lists all 8 problems with practice links.