Arrays and Strings· 15 min

Sliding Window (Max Sum)

Slide a fixed window with an O(1) running sum

Setup

Step 1 / 31

Current step

1 / 31

Build the first window [0..2]. Its sum is 15, so it becomes the first best window.

Step log

Build first window

Fixed window size k = 3

Current [0..2]Best [0..2]

Input array

CURRENT WINDOW
4
0
2
1
9
2
7
3
1
4
8
5
8
6
2
7
6
8
5
9
The first window is summed once; every later window reuses that total.

Window sum

15

Best sum

15

Moving window
Leaving value
Entering value
Best window
sliding-window.java
1public class Main {
2 public static int maxSumWindow(int[] arr, int k) {
3 if (k <= 0 || k > arr.length) throw new IllegalArgumentException("Invalid window size");
4 int sum = 0;
5 for (int i = 0; i < k; i++) sum += arr[i];
6 int best = sum;
7 for (int i = k; i < arr.length; i++) {
8 sum += arr[i] - arr[i - k];
9 best = Math.max(best, sum);
10 }
11 return best;
12 }
13
14}
● Java
Time
O(n)
Space
O(1)
Naive time
O(n·k)
Array size
10

Written guide

Sliding Window (Max Sum): complete guide

The fixed-size sliding window finds the maximum sum of any k consecutive elements by adding the element that enters the window and subtracting the one that leaves, instead of re-summing every window. That single idea drops the cost from O(n * k) to O(n).

Intuition

Say a shop wants its best three-day sales streak from a month of daily totals. The slow way is to add days 1 to 3, then days 2 to 4 from scratch, then days 3 to 5, and so on. But look at what changes between two neighbouring windows: one day falls off the front and one new day joins the back. Everything in the middle is identical. So keep a running total, subtract the day that leaves, add the day that arrives, and you get the next window's sum with two operations no matter how wide the window is.

It is like looking out of a train window: the frame stays the same width, and as the train moves, one telegraph pole slides out of view on one side while another slides in on the other. You do not need to recount every pole in the frame each second.

How it works step by step

  1. Check that 1 <= k <= n; otherwise there is no valid window.
  2. Sum the first k elements to get window, and set best = window.
  3. For each index i from k to n - 1: add nums[i] (the element entering on the right) and subtract nums[i - k] (the element leaving on the left).
  4. Update best = max(best, window).
  5. Return best. If you also need the position, record the start index i - k + 1 whenever best improves.

Dry run

Input [2, 1, 5, 1, 3, 2], window size k = 3.

StepWindow (indices)ElementsUpdateSumBest
Init0..2[2, 1, 5]2 + 1 + 588
i = 31..3[1, 5, 1]+1 (in), -2 (out)78
i = 42..4[5, 1, 3]+3 (in), -1 (out)99
i = 53..5[1, 3, 2]+2 (in), -5 (out)69

The answer is 9, from the window [5, 1, 3]. Every step did one addition and one subtraction, even though each window holds three numbers. With k = 1,000 the saving is a factor of about 500.

Code

MaxSumWindow.java
public class MaxSumWindow {
    /** Maximum sum of any k consecutive elements. Requires 1 <= k <= nums.length. */
    public static long maxSum(int[] nums, int k) {
        if (k <= 0 || k > nums.length) {
            throw new IllegalArgumentException("k must be between 1 and nums.length");
        }
        long window = 0;
        for (int i = 0; i < k; i++) window += nums[i];
        long best = window;
        for (int i = k; i < nums.length; i++) {
            window += (long) nums[i] - nums[i - k]; // one in, one out
            best = Math.max(best, window);
        }
        return best;
    }

    public static void main(String[] args) {
        System.out.println(maxSum(new int[] {2, 1, 5, 1, 3, 2}, 3)); // 9
        System.out.println(maxSum(new int[] {-4, -2, -7}, 2));      // -6
    }
}
max_sum_window.py
def max_sum_window(nums, k):
    """Maximum sum of any k consecutive elements (1 <= k <= len(nums))."""
    if not 1 <= k <= len(nums):
        raise ValueError("k must be between 1 and len(nums)")
    window = sum(nums[:k])
    best = window
    for i in range(k, len(nums)):
        window += nums[i] - nums[i - k]
        best = max(best, window)
    return best


print(max_sum_window([2, 1, 5, 1, 3, 2], 3))  # 9
print(max_sum_window([-4, -2, -7], 2))        # -6

The Java version accumulates in a long and casts before subtracting, so even values near the int limit cannot overflow. Python integers are unbounded, so no care is needed there.

Time and space complexity

ApproachBestAverageWorstSpace
Sliding windowO(n)O(n)O(n)O(1)
Brute force (re-sum each window)O(n * k)O(n * k)O(n * k)O(1)
Prefix sumsO(n)O(n)O(n)O(n)

The initial window costs k additions and each of the remaining n - k slides costs two operations, so the total is O(n) regardless of k. Only the running sum and the best value are stored. Prefix sums also give O(n), but they spend an extra array; their advantage is answering many different range queries later.

Edge cases

  • k == n: there is exactly one window and the loop body never runs.
  • k == 1: the answer is simply the maximum element.
  • k > n or k <= 0: no valid window; throw, or return whatever the problem specifies.
  • All negative numbers: initialise best from the first window, never from 0, or you will report a sum that no window has.
  • Very large values or long arrays: use a 64-bit accumulator.
  • Empty input: covered by the k > n check since any valid k is at least 1.

Common mistakes

  • Initialising `best = 0`. With all-negative input the true answer is negative, and 0 is wrong.
  • Off-by-one on the leaving element. When nums[i] enters, the element leaving is nums[i - k], not nums[i - k + 1] or nums[i - 1].
  • Forgetting to compare the first window. If you only update best inside the loop, the case k == n returns nothing meaningful.
  • Using a fixed window for a variable-size problem. 'Longest substring with at most k distinct characters' needs a window that grows and shrinks, driven by a condition, not a fixed width.
  • Confusing max sum with max element. 'Sliding window maximum' (the largest single value in each window) needs a monotonic deque, not a running sum.

Variations and when to use it

Fixed-size windows (this lesson) handle maximum or average of k consecutive elements, counting windows that satisfy a threshold, and the count of vowels in every length-k substring. Variable-size windows expand the right edge every step and shrink the left edge while the window violates a rule, which solves longest substring without repeats, minimum size subarray sum, and the 'flip at most k zeroes' family. Both are special cases of two pointers moving in the same direction.

Use a sliding window when the problem talks about a contiguous subarray or substring and the quantity you track can be updated incrementally as one element enters and one leaves (sums, counts, frequency maps). If elements are not contiguous, or the aggregate cannot be undone when an element leaves (like a maximum without a deque), you need a different tool. For the max sum of any length, not a fixed k, the right algorithm is Kadane's, not a window.

FAQ

›What is the sliding window technique?

It processes contiguous subarrays by maintaining a window between two indices and updating a summary of it incrementally as the window moves, instead of recomputing from scratch for each position.

›When should I use a fixed window versus a variable window?

Use a fixed window when the problem gives the length k. Use a variable window when it asks for the longest or shortest contiguous segment that satisfies a condition.

›Does the sliding window work with negative numbers?

The fixed-size max sum version works with any integers. Variable-size sum windows usually assume non-negative values, because with negatives, shrinking the window does not reliably decrease the sum; those problems need prefix sums with a hash map or a deque.

›Is this the same as Kadane's algorithm?

No. Kadane's finds the maximum sum subarray of any length. The sliding window here fixes the length at k. Both are O(n), but they answer different questions.

›Why is sliding window O(n) and not O(n * k)?

Each element is added to the running sum exactly once when it enters and subtracted exactly once when it leaves, so the total work is proportional to n, independent of the window size.