Beginner: foundations · Hashing, two pointers and sliding window · topic 14 of 61 · 30 min
Sliding window: fixed size
Explanation
What a window is
A window is a run of neighbouring items, described by where it starts and where it ends. A fixed-size window always holds exactly k items. Many questions ask about every window of size k: the best 7-day sales total, the average of every 24 hourly readings, or whether some stretch of a string is an anagram of a word. A list of n items has n − k + 1 windows of size k (when k ≤ n).
The slow way: recompute every window
Adding up k items for each of the n − k + 1 windows costs O(k) per window, so O(n × k) in total. With n = 100,000 days and k = 30 that is about 3 million additions; with k = 50,000 it is over a billion. sum(nums[i:i + k]) inside a loop is exactly this slow way, plus a copy of every slice.
The sliding trick
Two neighbouring windows share k − 1 items. When the window slides one step right, exactly one item enters (nums[i]) and one item leaves (nums[i − k]). So update the sum in O(1): window += nums[i] − nums[i − k]. Build the first window once, then slide. That is O(n) time in total and O(1) extra space.
| Window (indexes) | Enters | Leaves | Sum |
|---|---|---|---|
| 0..2 = [2, 1, 5] | — | — | 8 |
| 1..3 = [1, 5, 1] | 1 | 2 | 8 + 1 − 2 = 7 |
| 2..4 = [5, 1, 3] | 3 | 1 | 7 + 3 − 1 = 9 |
| 3..5 = [1, 3, 2] | 2 | 5 | 9 + 2 − 5 = 6 |
def max_window_sum(nums, k): # assumes 1 <= k <= len(nums)
window = sum(nums[:k])
best = window
for i in range(k, len(nums)):
window += nums[i] - nums[i - k] # one enters, one leaves
best = max(best, window)
return best
print(max_window_sum([2, 1, 5, 1, 3, 2], 3)) # Output: 9Averages over a window
A moving average (also called a rolling average) is the average of each window: window_sum / k. It smooths noisy data, which is why dashboards show 7-day averages of sales or 24-hour averages of air quality. When the data are integers, keep the running sum as an integer and divide only when you report, so small rounding errors do not build up. Round only the final values, for example round(avg, 2).
Windows of counts: anagram windows
A window can hold more than a sum. To count the windows of s that are anagrams of p (same characters, same counts), keep a count map of the current window of size len(p). When the window slides, add 1 for the entering character and subtract 1 for the leaving one. Compare the window's map with p's map at each step.
Delete a key when its count drops to 0. A plain dict that still holds a zero entry is not equal to one without that key, so equal windows would look different:
window = {"a": 1, "b": 0}
print(window == {"a": 1}) # Output: False (the zero entry still counts)
del window["b"]
print(window == {"a": 1}) # Output: TrueWith a fixed alphabet, such as 26 lowercase letters, comparing two maps is O(26) = O(1), so the whole scan is O(n). A faster variant keeps a single number, "how many characters currently have the right count", and updates it as counts change.
Edge cases to settle first
- k larger than n: there is no window at all. Decide what to return (None, [] or 0) and say it.
- k = 0 or negative: usually invalid; handle it the same way.
- Empty input: same as k > n.
- Negative numbers are fine for fixed windows. The size is fixed, so you never have to decide when to shrink; that decision is what makes Topic 5 harder.
Common mistakes
- Recomputing sum(nums[i:i + k]) for every window: O(n × k). Fix: slide with one add and one subtract.
- Off-by-one in the leaving index. Fix: when nums[i] enters, nums[i − k] leaves; check it by hand with k = 1.
- Starting best at 0, which is wrong when every window sum is negative. Fix: start best at the first window's sum.
- Not handling k > len(nums): sum(nums[:k]) quietly sums a too-short list and returns a wrong answer. Fix: check k first.
- Leaving zero counts in a dict window, so equal windows compare unequal. Fix: delete keys that reach 0.
Need help?
Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.
Try:
Watch the lesson
Sliding window: fixed size · 1/8
This lesson is about fixed-size sliding windows: runs of exactly k neighbouring items.
Prefer a video by a teacher? Find free videos on “sliding window fixed size maximum sum subarray of size k find all anagrams” on YouTube ↗
In real life: Smoothing air-quality readings
Air-quality dashboards, such as those built on government pollution data, often show the average of the most recent readings instead of one jumpy reading. Each new hour adds one reading and drops the oldest one, which is exactly a fixed-size sliding window. The example uses a window of 3 hours and made-up PM2.5 values to keep it short.
readings = [80, 95, 120, 150, 110, 90] # hourly PM2.5 values (made-up)
k = 3
window = sum(readings[:k])
averages = [round(window / k, 2)]
for i in range(k, len(readings)):
window += readings[i] - readings[i - k]
averages.append(round(window / k, 2))
print(averages)Practice (0/3 done)
sales[i] is a shop's sales on day i (it can be negative after returns). Write max_sum_k(sales, k) that returns the largest total of k CONSECUTIVE days. If k <= 0 or k > len(sales), return None. Use a sliding window: O(n) time, O(1) extra space. Example: max_sum_k([2, 1, 5, 1, 3, 2], 3) returns 9.
Write moving_averages(nums, k) that returns the average of every window of k consecutive numbers, from left to right, each rounded with round(value, 2). If k <= 0 or k > len(nums), return []. Keep a running sum (O(n) time). Example: moving_averages([1, 2, 3, 4, 5], 2) returns [1.5, 2.5, 3.5, 4.5].
Write count_anagram_windows(s, p) that returns how many windows of s of length len(p) are anagrams of p (same characters, same counts; case matters). p is never empty. Slide a window of counts: O(n) time for a fixed alphabet. Example: count_anagram_windows("cbaebabacd", "abc") returns 2 ("cba" at 0 and "bac" at 6).
Quick quiz
Read more (free)
Related help
Before this, learn
This topic builds on these. If something here feels new, open them first.
Related topics
- Sliding window: variable sizeHashing, two pointers and sliding window · same module
- Data-structure questions in JavaScriptJavaScript Programming (language in depth) · Interview preparation and career
- Running totals, moving averages and framesSQL and Databases · Window functions
- Monotonic stacks and queuesStacks, queues and linked lists
- Rate limitingBackend Development · Performance and reliability
- Strings: building, comparing and countingArrays and strings
Questions people ask about this
Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.
The window has size k and nums[i] just entered. Which item leaves?
Answer: nums[i − k]
The new window is i − k + 1 .. i, so the item just before it, nums[i − k], leaves.
n = 1,000,000 and k = 1,000. About how many steps do recomputing and sliding take?
Answer: About 10⁹ for recomputing, about 10⁶ for sliding
Recomputing costs about n × k; sliding does a constant amount of work per item.
The window [4, 2, 7] has sum 13. The next item is 1 and k = 3. What is the next window sum?
Answer: 10
13 − 4 (leaves) + 1 (enters) = 10, the sum of [2, 7, 1].
Why start best at the first window's sum instead of 0?
Answer: Because every window sum might be negative
If all sums are negative, starting at 0 would return 0, which is not the sum of any window.
How many windows of size k does a list of n items have (k ≤ n)?
Answer: n − k + 1
The window can start at 0, 1, …, n − k: that is n − k + 1 starts.
A loop with arr.indexOf inside it on the same array is…Related
Why is the variable sliding window O(n) even with a while loop inside the for loop?Related
Answer: left only moves forward, so it moves at most n times in total
Across the whole run each item is added once and removed at most once.
Which key puts exactly the anagrams of "listen" into one group AND can be used as a dict key?Related
Answer: "".join(sorted("listen"))
The sorted string is the same for all anagrams and is hashable. A set loses counts and is unhashable, a list is unhashable, and length groups unrelated words.
n items and q range-sum queries. What is the total cost with a prefix array?Related
Pass the quiz (60% or more) or mark this topic as done when you are ready.
Your progress is saved on this device only.
Next steps
- 1 more topic in “Hashing, two pointers and sliding window” before its exam: Sliding window: variable size.
- Module 3 exam: Hashing, two pointers and sliding window · 14 questions · 25 min, without help. 5 topics of this module still to finish first.
- Then the next module, Stacks, queues and linked lists. 61 topics left in the course before the final exam.