Maximum Sum Subarray of Size K

97.9k
0

Given an integer array nums and an integer k, find the maximum sum of any continuous subarray of size k.

A subarray is a contiguous part of the array.

Return the maximum sum among all subarrays of size k.

If no subarray of size k exists, return -1.

Example 1

Input: nums = [2, 1, 5, 1, 3, 2], k = 3

Output: 9

Explanation: All subarrays of size 3 are:

[2, 1, 5] has sum 8

[1, 5, 1] has sum 7

[5, 1, 3] has sum 9

[1, 3, 2] has sum 6

The maximum sum is 9.

Example 2

Input: nums = [1, 2], k = 3

Output: -1

Explanation: The array has only 2 elements, so no subarray of size 3 can be formed.

Example 3

Input: nums = [-3, -2, -5, -1], k = 2

Output: -5

Explanation: The subarrays of size 2 are [-3, -2], [-2, -5], and [-5, -1]. Their sums are -5, -7, and -6. The maximum among them is -5.

Brute Force Approach

Every possible starting position can form at most one subarray of size k. Calculating the sum of k consecutive elements from each valid starting position guarantees examination of every possible fixed-size subarray.

Overlapping subarrays contain many common elements. Recalculating every sum from the beginning repeats additions, producing a simple but inefficient solution.

Algorithm

  • Store the array size in n and return -1 when k <= 0 or n < k because no valid subarray can exist.

  • Initialize maxSum with the smallest possible value to support arrays containing only negative numbers.

  • Traverse every valid starting index i from 0 to n - k.

  • Initialize currentSum with 0 and add elements from index i through i + k - 1.

  • Update maxSum with the larger value between maxSum and currentSum after calculating each complete window.

  • Return maxSum after examination of every subarray of size k.

Dry Run

Maximum Sum of Subarray of Size K Brute Force Approach Dry Run.png

Maximum Sum of Subarray of Size K Brute Force Approach Dry Run.png

Solution

#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
long long maxSumSubarray(vector<int>& nums, int k) {
int n = nums.size();
// No subarray of size k can be formed.
if (k <= 0 || n < k) {
return -1;
}
long long maxSum = LLONG_MIN;
/*
* Calculate the complete sum for
* every possible window of size k.
*/
for (int start = 0; start <= n - k; start++) {
long long currentSum = 0;
for (int index = start; index < start + k; index++) {
currentSum += nums[index];
}
// Keep the largest window sum found so far.
if (currentSum > maxSum) {
maxSum = currentSum;
}
}
return maxSum;
}
};
int main() {
vector<int> nums = {2, 1, 5, 1, 3};
int k = 3;
Solution solution;
cout << solution.maxSumSubarray(nums, k) << endl;
return 0;
}

Complexity Analysis

Time Complexity: O(N × K), where N represents the array size. Every valid starting position may require addition of K elements.

Space Complexity: O(1), because only loop indices, currentSum, and maxSum require auxiliary storage.

Better Approach

A prefix sum array stores cumulative sums from the beginning of nums. The value at prefixSum[i] represents the sum of the first i elements.

For a subarray starting at index i and ending at index i + k - 1, subtracting prefixSum[i] from prefixSum[i + k] removes all elements before index i. Every fixed-size subarray sum can therefore be calculated in constant time.

Algorithm

  • Store the array size in n and return -1 when k <= 0 or n < k.

  • Create prefixSum with size n + 1 and initialize prefixSum[0] with 0.

  • Traverse nums and calculate prefixSum[i + 1] = prefixSum[i] + nums[i].

  • Initialize maxSum with the smallest possible value to support negative subarray sums.

  • Traverse every starting index i from 0 to n - k, calculate currentSum = prefixSum[i + k] - prefixSum[i], and update maxSum.

  • Return maxSum after processing every valid starting position.

Dry Run

Maximum Sum of Subarray of Size K Better Approach Dry Run.png

Maximum Sum of Subarray of Size K Better Approach Dry Run.png

Solution

#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
long long maxSumSubarray(vector<int>& nums, int k) {
int n = nums.size();
// No subarray of size k can be formed.
if (k <= 0 || n < k) {
return -1;
}
vector<long long> prefixSum(n + 1, 0);
/*
* prefixSum[i] stores the sum
* of the first i elements.
*/
for (int i = 0; i < n; i++) {
prefixSum[i + 1] = prefixSum[i] + nums[i];
}
long long maxSum = LLONG_MIN;
for (int start = 0; start <= n - k; start++) {
/*
* Subtract the prefix before start
* to get exactly k elements.
*/
long long currentSum =
prefixSum[start + k] - prefixSum[start];
if (currentSum > maxSum) {
maxSum = currentSum;
}
}
return maxSum;
}
};
int main() {
vector<int> nums = {2, 1, 5, 1, 3};
int k = 3;
Solution solution;
cout << solution.maxSumSubarray(nums, k) << endl;
return 0;
}

Complexity Analysis

Time Complexity: O(N), where N represents the array size. Prefix construction requires O(N) time, and examination of all fixed-size subarrays requires O(N) time.

Space Complexity: O(N), because prefixSum stores N + 1 cumulative values.

Optimal Approach

A fixed-size window can begin with the first k elements. Moving the window one position forward removes the leftmost element and includes one new element from the right.

Subtracting the outgoing element and adding the incoming element updates the window sum without recalculating all k values. Every element enters and leaves the window at most once.

Algorithm

  • Store the array size in n and return -1 when k <= 0 or n < k, because no subarray of exactly k elements can be formed.

  • Initialize windowSum with 0 and add the first k elements so it represents the sum of the first valid window.

  • Initialize maxSum with windowSum, since the first window provides the first valid candidate and also handles arrays containing only negative values.

  • Traverse i from k to n - 1, where nums[i] is the new element entering the window and nums[i - k] is the element leaving from its left side.

  • Update windowSum by adding nums[i] and subtracting nums[i - k], then update maxSum whenever the new window produces a larger sum.

  • Return maxSum after every fixed-size window has been processed.

Dry Run

Maximum Sum of Subarray of Size K Optimal Approach Dry Run.png

Maximum Sum of Subarray of Size K Optimal Approach Dry Run.png

Solution

#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
long long maxSumSubarray(vector<int>& nums, int k) {
int n = nums.size();
// No subarray of size k can be formed.
if (k <= 0 || n < k) {
return -1;
}
long long windowSum = 0;
// Build the first valid window.
for (int i = 0; i < k; i++) {
windowSum += nums[i];
}
long long maxSum = windowSum;
/*
* nums[i] enters the window while
* nums[i - k] leaves from the left.
*/
for (int i = k; i < n; i++) {
windowSum += nums[i];
windowSum -= nums[i - k];
// Keep the best fixed-size window sum.
if (windowSum > maxSum) {
maxSum = windowSum;
}
}
return maxSum;
}
};
int main() {
vector<int> nums = {2, 1, 5, 1, 3};
int k = 3;
Solution solution;
cout << solution.maxSumSubarray(nums, k) << endl;
return 0;
}

Complexity Analysis

Time Complexity: O(N), where N represents the array size. Initial window construction processes K elements, while the remaining traversal processes every later element once.

Space Complexity: O(1), because only windowSum, maxSum, and loop variables require auxiliary storage.

FAQS

Q1. Why does the prefix sum approach improve upon brute force?

Prefix sums calculate every subarray sum through one subtraction, avoiding repeated addition of K elements.

Q2. Why does prefixSum contain N + 1 positions?

The leading zero allows every subarray sum, including a subarray starting at index 0, to use the same subtraction formula.

Q3. Why is nums[i - k] removed during sliding-window traversal?

Index i - k represents the leftmost element of the previous window. Removal maintains exactly K elements inside the new window.

Q4. Does the sliding-window approach support negative values?

Yes. Initialization from the first valid window prevents an incorrect default answer of 0 for arrays containing only negative values.

Q5. What happens when k equals the array size?

Only one valid subarray exists, so the sum of the complete array becomes the answer.

Sliding WindowArrays

Read Similar Blogs

Comments0