Problem overview
The method MaxSum receives an int[] nums and a positive int k. It must find the contiguous subarray of length exactly k with the largest sum, and return its first and last index as an int[].
For nums = [5, 6, 1, 2, 6, 6, 4, 3] and k = 3, the best window is [6, 6, 4], which sums to 16 and sits at indices 4 to 6. The method returns [4, 6]. When two windows have the same sum, the lesson's steps return the earlier one.
Approach: slide the window instead of re-adding it
The brute-force lesson on this problem adds up k elements for every window, which costs O(n * k). But two neighbouring windows share k - 1 elements. Moving the window one step to the right changes exactly two things: the leftmost element leaves, and a new element enters on the right. So the new sum is the old sum, minus the element that left, plus the element that entered. That is two operations per window, whatever k is.
The plan is to compute the first window's sum the slow way, once, and then slide across the rest of the array updating the sum in constant time. The total work is one pass over the array, which is O(n).
Step by step
- Start the answer at the first window.
answeris{0, k - 1}. If no later window has a bigger sum, the first one is the answer, so it is the right default. Starting with an empty array would return nothing whenever the first window is the best. - Add up the first window. A loop over the indices 0 to
k - 1accumulatessum. - Record it as the best so far.
maxSumis initialised fromsum. - Slide. A second loop runs
ifrom 1 tonums.Length - kinclusive, whereiis the start of the current window. The condition uses<=because the last window begins atnums.Length - k. - Update the sum. The previous window started at
i - 1, sonums[i - 1]has just left. The current window ends ati + k - 1, sonums[i + k - 1]has just entered. - Compare. If the new
sumis strictly greater thanmaxSum, update bothmaxSumandanswer. The strict comparison keeps the earlier window on a tie. - Return
answer.
Traced on the example, the sums are 12 for the first window, then 12 - 5 + 2 = 9, then 9 - 6 + 6 = 9, then 9 - 1 + 6 = 14, then 14 - 2 + 4 = 16, then 16 - 6 + 3 = 13. The best is 16, found when i = 4, so answer ends up as {4, 6}.
The solution in C#
class Solution {
public int[] MaxSum(int[] nums, int k) {
int[] answer = new int[]{0, k - 1};
int sum = 0;
for (int i = 0; i < k; i++) {
sum += nums[i];
}
int maxSum = sum;
for (int i = 1; i <= nums.Length - k; i++) {
sum = sum - nums[i - 1] + nums[i + k - 1];
if (sum > maxSum) {
maxSum = sum;
answer = new int[]{i, i + k - 1};
}
}
return answer;
}
}
C# details worth noticing
- Two loops, two scopes. Both loops declare their own
int i. That is allowed because eachiexists only inside its ownforstatement. Declaringitwice in the same scope would not compile. - Array initialisers.
new int[]{0, k - 1}creates a two-element array whose values can be any expressions, not just constants. Arrays can't grow, so each improvement creates a fresh array. - Overflow. If the array held values near the
intlimits, the running sum could wrap around without any error. The lesson's data stays small.
Why the update is safe
The update works because the window sum is always the sum of exactly the elements currently inside the window. Before the update it covers indices i - 1 to i + k - 2. Removing the first and adding the one after the last leaves indices i to i + k - 1, which is the new window. Nothing else changes, so no element is ever counted twice or missed.
Complexity
Time: O(n). The first loop does k additions and the second does n - k iterations of constant work, so about n steps in total, regardless of k.
Space: O(1) beyond the two-element result.
Edge cases and common mistakes
- Using the wrong element for entering or leaving. Subtracting
nums[i]or addingnums[i + k]is a common off-by-one. Check withi = 1: the window is indices 1 tok, so the leaving element is index 0 and the entering one is indexk, which isi + k - 1. kequal to the array length. There is exactly one window. The second loop starts at 1 and the condition1 <= 0is false, so the method returns{0, k - 1}.klarger than the array. The first loop reads past the end ofnumsand throws anIndexOutOfRangeException. The lesson's inputs always havekwithin the length, but code that accepts arbitrary input should check first.- All negative numbers. Initialising
maxSumfrom the first window, rather than 0, makes this work. For[-3, -1, -2]withk = 2, the sums are -4 and -3, so the answer is[1, 2]. - Ties. The strict
>keeps the earlier window:[2, 1, 1, 2]withk = 2returns[0, 1].
Key takeaways
- When consecutive subarrays overlap almost completely, update the sum instead of recomputing it.
- Seed the best value from the first real candidate, not from 0.
- The loop's last start index is
nums.Length - k, which needs<=.