🧠
Prefix Sum Array (Alternative Optimal)
💡 This approach uses prefix sums to compute subarray sums in O(1) after O(n) preprocessing, offering an alternative to sliding window with similar efficiency.
Intuition
Precompute prefix sums so that sum of any subarray can be found by subtracting two prefix sums. Then iterate over all subarrays of length k to find the maximum sum.
Algorithm
- Create a prefix sum array where prefix[i] is sum of nums[0..i-1].
- Iterate over all subarrays of length k using prefix sums to get their sums in O(1).
- Track the maximum sum found.
- Return the maximum sum divided by k.
💡 The key is to understand how prefix sums allow constant-time subarray sum queries.
def findMaxAverage(nums, k):
n = len(nums)
prefix = [0] * (n + 1)
for i in range(n):
prefix[i + 1] = prefix[i] + nums[i]
max_sum = float('-inf')
for i in range(k, n + 1):
current_sum = prefix[i] - prefix[i - k]
if current_sum > max_sum:
max_sum = current_sum
return max_sum / k
# Driver code
if __name__ == '__main__':
nums = [1,12,-5,-6,50,3]
k = 4
print(findMaxAverage(nums, k)) # Expected output: 12.75
Line Notes
prefix = [0] * (n + 1)Initialize prefix sum array with extra space to handle sums easily.
prefix[i + 1] = prefix[i] + nums[i]Build prefix sums cumulatively to enable O(1) subarray sum queries.
current_sum = prefix[i] - prefix[i - k]Calculate sum of subarray using prefix sums efficiently.
if current_sum > max_sum:Update max_sum if current sum is greater to track maximum.
public class Solution {
public static double findMaxAverage(int[] nums, int k) {
int n = nums.length;
int[] prefix = new int[n + 1];
prefix[0] = 0;
for (int i = 0; i < n; i++) {
prefix[i + 1] = prefix[i] + nums[i];
}
int maxSum = Integer.MIN_VALUE;
for (int i = k; i <= n; i++) {
int currentSum = prefix[i] - prefix[i - k];
if (currentSum > maxSum) {
maxSum = currentSum;
}
}
return (double) maxSum / k;
}
public static void main(String[] args) {
int[] nums = {1,12,-5,-6,50,3};
int k = 4;
System.out.println(findMaxAverage(nums, k)); // Expected output: 12.75
}
}
Line Notes
int[] prefix = new int[n + 1];Create prefix sum array with extra space for easy indexing.
prefix[i + 1] = prefix[i] + nums[i];Build prefix sums cumulatively for O(1) subarray sum queries.
int currentSum = prefix[i] - prefix[i - k];Calculate subarray sum in O(1) using prefix sums.
if (currentSum > maxSum)Update maxSum if current sum is greater to track maximum.
#include <iostream>
#include <vector>
#include <climits>
using namespace std;
double findMaxAverage(vector<int>& nums, int k) {
int n = nums.size();
vector<int> prefix(n + 1, 0);
for (int i = 0; i < n; i++) {
prefix[i + 1] = prefix[i] + nums[i];
}
int maxSum = INT_MIN;
for (int i = k; i <= n; i++) {
int currentSum = prefix[i] - prefix[i - k];
if (currentSum > maxSum) {
maxSum = currentSum;
}
}
return (double)maxSum / k;
}
int main() {
vector<int> nums = {1,12,-5,-6,50,3};
int k = 4;
cout << findMaxAverage(nums, k) << endl; // Expected output: 12.75
return 0;
}
Line Notes
vector<int> prefix(n + 1, 0);Initialize prefix sum vector with zeros for easy indexing.
prefix[i + 1] = prefix[i] + nums[i];Build prefix sums cumulatively for efficient queries.
int currentSum = prefix[i] - prefix[i - k];Calculate subarray sum in O(1) using prefix sums.
if (currentSum > maxSum)Update maxSum if current sum is greater to track maximum.
function findMaxAverage(nums, k) {
const n = nums.length;
const prefix = new Array(n + 1).fill(0);
for (let i = 0; i < n; i++) {
prefix[i + 1] = prefix[i] + nums[i];
}
let maxSum = -Infinity;
for (let i = k; i <= n; i++) {
let currentSum = prefix[i] - prefix[i - k];
if (currentSum > maxSum) {
maxSum = currentSum;
}
}
return maxSum / k;
}
// Test
const nums = [1,12,-5,-6,50,3];
const k = 4;
console.log(findMaxAverage(nums, k)); // Expected output: 12.75
Line Notes
const prefix = new Array(n + 1).fill(0);Initialize prefix sum array with zeros for easy indexing.
prefix[i + 1] = prefix[i] + nums[i];Build prefix sums cumulatively for efficient subarray sum queries.
let currentSum = prefix[i] - prefix[i - k];Calculate subarray sum in O(1) using prefix sums.
if (currentSum > maxSum)Update maxSum if current sum is greater to track maximum.
Prefix sums are computed in O(n), then each subarray sum is computed in O(1) for O(n) total. Space is O(n) for prefix array.
💡 For n=100,000, this means 100,000 operations plus storing 100,000 prefix sums, which is efficient but uses extra memory.
Interview Verdict: Accepted / Optimal alternative
This approach is also optimal and useful when multiple subarray sum queries are needed.