Skip to main content

Someone wanted to learn this too, so Grasp built them a personal learning path.

You can keep exploring this one or create your own

Solving Fixed-Size Window Problems with Sliding-Window Updates

Hello! Last time, you used two pointers to take advantage of a sorted array’s order or to compare positions in a string. A sliding window also uses positions, but its purpose is different: it keeps track of a contiguous part of a sequence as that part moves.

Today you’ll solve problems that ask about every subarray or substring of a specified length. The central skill is updating a window’s state without rebuilding it from scratch. This is a useful pattern for timed DSA problems because it often turns repeated work into a single pass.


Why neighboring windows are related

Suppose nums = [2, 1, 5, 1, 3, 2] and you need the largest sum of any three consecutive elements. The first window is [2, 1, 5], with sum 8. The next is [1, 5, 1], with sum 7.

You could add all three values again for each position. But the two windows share 1 and 5. To get the new sum, remove the 2 that left and add the 1 that entered: 8 - 2 + 1 = 7. Each later shift has the same shape—one value leaves, one enters—regardless of how large the window is.

Watch Greg Hogg’s Sliding Window Algorithm - Variable Length + Fixed Length - DSA Course in Python Lecture 13. Use only its fixed-length example: it finds a maximum average, but because every candidate window has the same length, the update you need is the same running-sum update.

Sliding Window Algorithm - Variable Length + Fixed Length - DSA Course in Python Lecture 13

Greg Hogg works through a fixed-length maximum-average problem, from forming the first window to implementing its update in Python.

Watch the fixed window. Pay particular attention to why the element entering at index i replaces the element at index i - k, and why the first complete window must be evaluated before sliding begins. Stop when this example ends; the video’s earlier variable-length material is not needed here.

A fixed-size window is a good candidate when the prompt specifies a length k and asks you to inspect contiguous portions of an array or string. A pair of values anywhere in an array is not a window; three consecutive values are. If the required length is not known in advance, a different sliding-window pattern may be needed later in the course.


Build the first window, then update it

Let n be the length of nums, and assume 1 <= k <= n. The first window occupies indices 0 through k - 1. Once you know its sum, consider an incoming value at index i, starting with i = k. The value leaving is at index i - k.

For our example, the sums evolve as follows:

Window Update from the previous sum Sum
[2, 1, 5] Add the first k values 8
[1, 5, 1] Remove 2, add 1 7
[5, 1, 3] Remove 1, add 3 9
[1, 3, 2] Remove 5, add 2 6

Read Hello Interview’s Fixed Length Sliding Window alongside that trace. Its solution uses a slightly different loop arrangement—it grows a window to size k, evaluates it, then removes the leftmost value in preparation for the next iteration. That is the same accounting principle as initializing the first window separately and then shifting it.

Fixed Length Sliding Window

Hello Interview gives a maximum-sum example and a reusable fixed-window template. Read it to see which parts of the update stay the same across problems.

In “Fixed-Length Sliding Window,” begin with the window rule. Then, under “Problem: Maximum Sum of Subarray with Size K,” read the example and the update explanation. Continue through the Python function under “Solution” and the pseudocode under “Template.” Focus on when each version evaluates a complete window and when it removes the outgoing value; do not treat the two loop arrangements as separate algorithms.

Here is the first-window-then-slide arrangement in Python:

def max_sum_size_k(nums, k):
    if not 1 <= k <= len(nums):
        raise ValueError("k must be between 1 and len(nums)")

    window_sum = 0
    for i in range(k):
        window_sum += nums[i]

    best = window_sum  # The first complete window counts.

    for i in range(k, len(nums)):
        window_sum -= nums[i - k]  # Value leaving on the left
        window_sum += nums[i]      # Value entering on the right
        best = max(best, window_sum)

    return best

range(k, len(nums)) begins at the first value not already in the initial window. On its first iteration, i - k is 0, precisely the index that must leave. On its last iteration, i is len(nums) - 1, so the final window is included without reading beyond the list.

Initializing best from the first window matters. Starting it at 0 would give a wrong answer if every size-k window had a negative sum. The function also makes its input contract explicit: an empty list cannot contain a positive-length window, and k cannot exceed the list length.


Why the update is correct—and faster

Immediately after forming the first window, window_sum equals the sum of nums[0:k]. For each later index i, assume it holds the sum of the preceding size-k window. That window contains nums[i - k] but not nums[i]; the next window contains nums[i] but not nums[i - k]. Subtracting the former and adding the latter therefore produces exactly the next window’s sum. Updating best after that shift means it records the largest sum seen so far.

This also explains the boundaries. There are valid windows: one starting at index 0, and the last starting at index n-k. When k == n, the first window is also the last, so the sliding loop correctly does nothing. When k == 1, each update simply replaces one element with the next. Negative numbers require no change to the update rule.

If you recalculate each window’s sum from scratch, you may do work for each of windows. Here, building the first window costs , and each of the remaining shifts costs . Total time is , with auxiliary space. The window is represented by its running sum; the code does not create a new sublist for every position.


Keep the window update; change what you record

A maximum is only one possible question about fixed-length windows. Suppose instead you must count size-k subarrays whose sum equals target. The window state is still a running sum, and the same two values change on every shift. What changes is the result you maintain: a count rather than a maximum.

def count_windows_with_sum(nums, k, target):
    if not 1 <= k <= len(nums):
        raise ValueError("k must be between 1 and len(nums)")

    window_sum = 0
    for i in range(k):
        window_sum += nums[i]

    count = int(window_sum == target)  # Check the first window.

    for i in range(k, len(nums)):
        window_sum -= nums[i - k]
        window_sum += nums[i]
        if window_sum == target:
            count += 1

    return count

For nums = [2, -1, 2, -1, 2], k = 3, and target = 3, the three window sums are 3, 0, and 3, so the function returns 2. Notice that a window may contain negative values: fixed length tells you when to remove an element, so you do not need to infer a pointer move from whether the sum is too large or too small.

The same distinction applies to maximum average. Since every window has the same positive length k, the window with the greatest sum also has the greatest average. Find the maximum sum, then divide that result by k. More generally, choose a window state that can be updated efficiently, and separately decide whether the problem asks you to maximize it, count matches, or report something else about each complete window.


Key takeaways

For a fixed-length window, establish the first k elements and evaluate that first window. On each shift, remove the outgoing element from your state, add the incoming element, and evaluate the new window. For running sums, this visits all windows in time and auxiliary space.

Next, you’ll apply the related boundary-management idea to binary search: rather than updating a contiguous window’s contents, you’ll narrow a search interval in a sorted sequence without off-by-one errors.

Can't find a good explanation? Sign up and we'll make it for you

Sign up