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 <= 0orn < kbecause 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
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 <= 0orn < k.Create prefixSum with size
n + 1and initializeprefixSum[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, calculatecurrentSum = 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
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
nand return-1whenk <= 0orn < k, because no subarray of exactlykelements can be formed.Initialize
windowSumwith0and add the firstkelements so it represents the sum of the first valid window.Initialize
maxSumwithwindowSum, since the first window provides the first valid candidate and also handles arrays containing only negative values.Traverse
ifromkton - 1, wherenums[i]is the new element entering the window andnums[i - k]is the element leaving from its left side.Update
windowSumby addingnums[i]and subtractingnums[i - k], then updatemaxSumwhenever the new window produces a larger sum.Return
maxSumafter every fixed-size window has been processed.
Dry Run
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.
Be the first to add a comment.