Problem overview
The method maxSum receives an array of integers nums and a positive integer k. It looks at every contiguous block of exactly k elements (a "window"), finds the block with the largest sum, and returns the first and last index of that block as an int[] of two numbers.
For nums = [5, 6, 1, 2, 6, 6, 4, 3] and k = 3, the windows and their sums are:
| Start | Window | Sum |
|---|---|---|
| 0 | 5, 6, 1 | 12 |
| 1 | 6, 1, 2 | 9 |
| 2 | 1, 2, 6 | 9 |
| 3 | 2, 6, 6 | 14 |
| 4 | 6, 6, 4 | 16 |
| 5 | 6, 4, 3 | 13 |
The largest sum is 16, found in the window that starts at index 4 and ends at index 6, so the result is [4, 6]. The method reports positions, not the sum itself.
Approach: try every window
The most direct idea is to do exactly what the table does: for every possible start position, add up the k elements of that window, and remember the best sum seen so far together with the window's bounds.
How many windows are there? A window of length k can start at index 0, 1, and so on up to nums.length - k, after which it would run past the end. That gives n - k + 1 windows, where n is the array length. Each window costs k additions, so the total is about (n - k + 1) * k operations, which is O(n * k).
This is the brute-force solution, and it is a good first step because it is easy to get right. It repeats work, though: neighbouring windows share k - 1 elements, yet each sum is rebuilt from scratch. The sliding-window technique, covered in the other lesson on this problem, updates the sum by adding one element and removing one, bringing the time down to O(n). Understanding the brute force makes that improvement easy to see.
Step by step
- Track the best sum. Declare
maxSumand start it atInteger.MIN_VALUE, the smallest possibleint. Whatever the first window's sum is, even a very negative one, it is at least that large and replaces it. - Prepare the answer.
answerstarts as an emptyint[]. It is never filled in place: each time a better window turns up,answeris pointed at a new two-element array. - Loop over window starts. The index
iruns from 0 up to and includingnums.length - k. The condition is<=because the last window starts exactly atnums.length - k. - Reset the window sum. Inside this loop, declare
sumas 0. It lives inside the loop so each window begins from zero. - Loop over the window. The index
idxgoes fromiwhile it is less thani + k, which visits exactlykpositions. - Add each element
nums[idx]tosum. - Compare with the best. If
sumis strictly greater thanmaxSum, store it inmaxSumand setanswerto{i, i + k - 1}. The strict comparison means that when two windows tie, the earlier one is kept. - Return
answerafter both loops finish.
The solution in Java
class Solution {
public int[] maxSum(int[] nums, int k) {
int maxSum = Integer.MIN_VALUE;
int[] answer = new int[]{};
for (int i = 0; i <= nums.length - k; i++) {
int sum = 0;
for (int idx = i; idx < i + k; idx++) {
sum += nums[idx];
}
if (sum > maxSum) {
maxSum = sum;
answer = new int[]{i, i + k - 1};
}
}
return answer;
}
}
The Java details worth knowing:
- A local variable named like the method. The method is
maxSumand the local variable inside it is alsomaxSum. Java keeps method names and variable names apart, so this compiles, but a different name would be easier to read in code of your own. - Arrays are created with a size or with values.
new int[]{}is an array of length 0, andnew int[]{i, i + k - 1}is an array of length 2 holding those two values. Array lengths are fixed, which is why the answer is replaced rather than extended. nums.lengthis a field, without parentheses. Writingnums.length()is a compile error. That differs fromString.length()andList.size().intsums can overflow. Adding many large values can pass 2,147,483,647 and wrap around to a negative number without any error. For arrays with big values, declaresumandmaxSumaslong.
Complexity
Time: O(n * k). The outer loop runs n - k + 1 times and the inner loop runs k times per window. When k is small this is close to linear, and when k is around n / 2 it grows like n². The sliding window brings it to O(n).
Space: O(1). The method keeps a few integers and a two-element array, regardless of the input size.
Edge cases and common mistakes
kequals the array length. There is exactly one window, and the loop runs once withi = 0. For[1, 2, 3]andk = 3, the result is[0, 2].kis 1. Every window is one element, so the answer is the first position of the largest element, written twice:[1, 1]for[4, 9, 7], and[0, 0]for[4].- All negative numbers.
[-3, -1, -2]withk = 2returns[1, 2](sum -3, better than -4). This is whymaxSumstarts atInteger.MIN_VALUEand not at 0: with 0, no negative sum would ever win, andanswerwould stay empty. - Ties. For
[3, 3, 3, 3]andk = 2every window sums to 6, and the answer is[0, 1], the earliest. Changing>to>=would return the last one instead. klarger than the array. The loop conditioni <= nums.length - kis false at once, so the method returns the empty array. It does not crash.- Off-by-one in the loop bound. Using
i < nums.length - kskips the last window. Usingi < nums.lengthmakes the inner loop read past the end and throwArrayIndexOutOfBoundsException. - Returning the sum. The expected result is the pair of indices, not the value 16.
Testing
[5, 6, 1, 2, 6, 6, 4, 3]withk = 3gives[4, 6].[1, 2, 3]withk = 3gives[0, 2].[-3, -1, -2]withk = 2gives[1, 2].[4]withk = 1gives[0, 0].[3, 3, 3, 3]withk = 2gives[0, 1].
