Problem overview
The method maxSum receives an array nums of integers and a positive integer k. Among all continuous subarrays of length exactly k, it must find the one with the largest sum, and return its first and last index as a two-element array [start, end].
For nums = [5, 6, 1, 2, 6, 6, 4, 3] and k = 3, the window at indices 4 to 6 holds 6, 6, 4, which sums to 16, the largest of all windows of three. The method returns [4, 6].
Approach: add up every window
A window of length k is fixed by where it starts. If it starts at index i, it covers indices i to i + k - 1. The last window must still fit in the array, so the last start is nums.length - k. An array of length n therefore has n - k + 1 windows.
The brute-force idea is direct: for each start, add up the k elements of its window, and remember the best sum together with the indices that produced it. It does the same additions again and again for overlapping windows, which is wasteful, and the next lesson on this problem removes that waste. Here the goal is a correct, simple version first.
Here is the search on the example. The windows of length 3 and their sums are:
start 0: 5 + 6 + 1 = 12
start 1: 6 + 1 + 2 = 9
start 2: 1 + 2 + 6 = 9
start 3: 2 + 6 + 6 = 14
start 4: 6 + 6 + 4 = 16
start 5: 6 + 4 + 3 = 13
There are 8 - 3 + 1 = 6 windows, and the largest sum is 16 at start 4.
Look at starts 3 and 4 above: the two windows share the elements 6 and 6, yet the brute force adds them twice. Each window differs from its neighbour by one element leaving and one entering. Spotting that overlap is the whole idea behind the faster solution, which updates the sum in constant time per window.
Step by step
- Track the best sum.
maxSumstarts atNumber.NEGATIVE_INFINITY, which is smaller than any real sum, so the first window always replaces it. Starting at 0 would fail when every window sum is negative. - Prepare the answer.
answeris an emptynumber[]. It will hold the two indices of the best window so far. - Loop over window starts with
ifrom 0 up tonums.length - k, inclusive. The condition is<=, because a window starting atnums.length - kends exactly at the last element. - Reset the sum for each window:
sumis declared as 0 inside the loop. - Loop over the window. The inner index
idxruns fromiwhileidx < i + k, which visits exactlykpositions. - Add
nums[idx]tosum. - Compare. If
sumis strictly greater thanmaxSum, updatemaxSumand replaceanswerwith[i, i + k - 1]. The strict comparison means that when two windows tie, the earlier one stays. - Return
answerafter the loops.
The solution in TypeScript
class Solution {
maxSum(nums: number[], k: number): number[] {
let maxSum = Number.NEGATIVE_INFINITY;
let answer: number[] = [];
for (let i = 0; i <= nums.length - k; i++) {
let sum = 0;
for (let idx = i; idx < i + k; idx++) {
sum += nums[idx];
}
if (sum > maxSum) {
maxSum = sum;
answer = [i, i + k - 1];
}
}
return answer;
}
}
Some TypeScript details:
- The local variable shares the method's name. The method is
maxSumand the variable inside it is alsomaxSum. That is legal: the method lives on the class and is reached withthis.maxSum, while the variable is local to the body. It can confuse readers, so a name such asbestwould be clearer in your own code. - The empty array needs its annotation. With the annotation
let answer: number[] = [];the variable has a clear type. Without it,let answer = []would be typed from later assignments, which is less obvious. - Replace, don't mutate.
answer = [i, i + k - 1]makes a new array each time a better window appears. The old arrays are simply dropped. - Inclusive indices. A window
[i, i + k - 1]is inclusive on both ends. Remember that when you use the result: with[4, 6]andk = 3, the window holds three elements,nums[4],nums[5]andnums[6].
Complexity
Time: O(n * k). There are n - k + 1 windows, and each costs k additions. When k is about half of n this is quadratic. When k is 1 or equals n, it is linear.
Space: O(1). Besides the two-element answer, the method keeps a few numbers.
Edge cases and common mistakes
- Ties. For
[4, 4, 4]andk = 2the method returns[0, 1], the earliest window, because the second window's equal sum does not pass the strict>. - The last window. For
[9, 1, 1]andk = 2the loop must reach start 1. Writingi < nums.length - kwould stop at start 0 and never try[1, 1]. - All negative. For
[-3, -1, -2]andk = 1the answer is[1, 1], the single element -1. This only works becausemaxSumstarts at negative infinity. kequal to the length. For[7, 1]andk = 2there is one window, and the method returns[0, 1].- Forgetting to reset
sum. Ifsumis declared outside the outer loop, every window adds on top of the previous one. - Window longer than the array. If
kis larger thannums.length, the loop never runs and the method returns[]. The lesson's inputs don't do this.
Testing
[5, 6, 1, 2, 6, 6, 4, 3]withk = 3gives[4, 6].[4, 4, 4]withk = 2gives[0, 1].[9, 1, 1]withk = 2gives[0, 1].[-3, -1, -2]withk = 1gives[1, 1].