Given an array arr[] of size n and a positive integer k, find the subarray of length k with the maximum average.
- You need to return the starting index of the subarray.
- If there are multiple subarrays with the same maximum average, return the smallest starting index.
Example:
Input: k = 4, arr[] = [1, 12, -5, -6, 50, 3]
Output: 1
Explanation: Maximum average is (12 - 5 - 6 + 50)/4 = 51/4.Input: k = 3, arr[] = [3, -435, 335, 10, -50, 100, 20]
Output: 2
Explanation: Maximum average is (335 + 10 - 50)/3 = 295/3.
Table of Content
[Naive Approach] Using Nested Loops – O(n * k) Time and O(1) Space
The idea is to check every possible subarray of size
kand calculate its sum separately. For each starting index, we iterate through the nextkelements to compute the current subarray sum. The subarray having the maximum sum will also have the maximum average since the subarray size remains fixed.
- Iterate through all possible starting indices of subarrays of size
k - Compute the sum of each subarray using an inner loop
- Compare the current sum with the maximum sum found so far
- Store and return the starting index of the maximum sum subarray
#include<bits/stdc++.h>
using namespace std;
// Returns starting index of maximum
// average subarray
int findMaxAverage(vector<int>& arr, int k)
{
// Check if k is valid
if(k > arr.size())
{
return -1;
}
int max_sum = INT_MIN;
int start_index = 0;
// Check every subarray of size k
for(int i = 0; i <= arr.size() - k; i++)
{
int curr_sum = 0;
// Find sum of current subarray
for(int j = i; j < i + k; j++)
{
curr_sum += arr[j];
}
// Update maximum sum
if(curr_sum > max_sum)
{
max_sum = curr_sum;
start_index = i;
}
}
return start_index;
}
// Driver code
int main()
{
vector<int> arr = {1, 12, -5, -6, 50, 3};
int k = 4;
cout << "The maximum average subarray of "
<< "length " << k << " begins at index "
<< findMaxAverage(arr, k);
return 0;
}
import java.util.*;
class Solution {
public int findMaxAverage(List<Integer> arr, int k) {
if (k > arr.size()) {
return -1;
}
int max_sum = Integer.MIN_VALUE;
int start_index = 0;
for (int i = 0; i <= arr.size() - k; i++) {
int curr_sum = 0;
for (int j = i; j < i + k; j++) {
curr_sum += arr.get(j);
}
if (curr_sum > max_sum) {
max_sum = curr_sum;
start_index = i;
}
}
return start_index;
}
}
public class Main {
public static void main(String[] args) {
List<Integer> arr = Arrays.asList(1, 12, -5, -6, 50, 3);
int k = 4;
Solution ob = new Solution();
int ans = ob.findMaxAverage(arr, k);
System.out.println("The maximum average subarray of length " + k + " begins at index " + ans);
}
}
# Python program to find starting index of maximum average subarray
# Returns starting index of maximum average subarray
def findMaxAverage(arr, k):
# Check if k is valid
if k > len(arr):
return -1
max_sum = float('-inf')
start_index = 0
# Check every subarray of size k
for i in range(len(arr) - k + 1):
curr_sum = 0
# Find sum of current subarray
for j in range(i, i + k):
curr_sum += arr[j]
# Update maximum sum
if curr_sum > max_sum:
max_sum = curr_sum
start_index = i
return start_index
# Driver code
if __name__ == "__main__":
arr = [1, 12, -5, -6, 50, 3]
k = 4
print(f"The maximum average subarray of length {k} begins at index {findMaxAverage(arr, k)}")
// C# program to find starting index of maximum average subarray
using System;
class GfG {
// Returns starting index of maximum average subarray
static int findMaxAverage(int[] arr, int k) {
// Check if k is valid
if (k > arr.Length) {
return -1;
}
int max_sum = int.MinValue;
int start_index = 0;
// Check every subarray of size k
for (int i = 0; i <= arr.Length - k; i++) {
int curr_sum = 0;
// Find sum of current subarray
for (int j = i; j < i + k; j++) {
curr_sum += arr[j];
}
// Update maximum sum
if (curr_sum > max_sum) {
max_sum = curr_sum;
start_index = i;
}
}
return start_index;
}
// Driver code
static void Main(string[] args) {
int[] arr = {1, 12, -5, -6, 50, 3};
int k = 4;
Console.WriteLine("The maximum average subarray of length " + k +
" begins at index " + findMaxAverage(arr, k));
}
}
// JavaScript program to find starting index of maximum average subarray
// Returns starting index of maximum average subarray
function findMaxAverage(arr, k) {
// Check if k is valid
if (k > arr.length) {
return -1;
}
let max_sum = -Infinity;
let start_index = 0;
// Check every subarray of size k
for (let i = 0; i <= arr.length - k; i++) {
let curr_sum = 0;
// Find sum of current subarray
for (let j = i; j < i + k; j++) {
curr_sum += arr[j];
}
// Update maximum sum
if (curr_sum > max_sum) {
max_sum = curr_sum;
start_index = i;
}
}
return start_index;
}
// Driver code
const arr = [1, 12, -5, -6, 50, 3];
const k = 4;
console.log(`The maximum average subarray of length ${k} begins at index ${findMaxAverage(arr, k)}`);
Output
The maximum average subarray of length 4 begins at index 1
[Optimal Approach] Using Prefix Sum – O(n) Time and O(n) Space
The idea is to use a cumulative sum array to quickly calculate the sum of any subarray of length
k. Instead of recomputing sums for every subarray, we store prefix sums where each position contains the sum of all previous elements. Using these prefix sums, the sum of a subarray can be obtained in constant time, allowing us to efficiently find the subarray with maximum average.
- Build a cumulative sum array where each index stores prefix sum till that position
- Compute sum of first subarray of length
kand initialize maximum sum - For every next subarray, calculate its sum using prefix sums
- Track the subarray with maximum sum and return its starting index
#include<bits/stdc++.h>
using namespace std;
// Returns beginning index of maximum average
// subarray of length 'k'
int findMaxAverage(vector<int>& arr, int k)
{
// Check if 'k' is valid
if (k > arr.size())
return -1;
// Create and fill vector to store cumulative
// sum. csum[i] stores sum of arr[0] to arr[i]
vector<int> csum(arr.size());
csum[0] = arr[0];
for (int i = 1; i < arr.size(); i++)
csum[i] = csum[i - 1] + arr[i];
// Initialize max_sum as sum of first subarray
int max_sum = csum[k - 1];
int max_end = k - 1;
// Find sum of other subarrays and update
// max_sum if required
for (int i = k; i < arr.size(); i++)
{
int curr_sum = csum[i] - csum[i - k];
if (curr_sum > max_sum)
{
max_sum = curr_sum;
max_end = i;
}
}
// Return starting index
return max_end - k + 1;
}
// Driver program
int main()
{
vector<int> arr = {1, 12, -5, -6, 50, 3};
int k = 4;
cout << "The maximum average subarray of "
<< "length " << k << " begins at index "
<< findMaxAverage(arr, k);
return 0;
}
import java.util.*;
class Solution {
public int findMaxAverage(List<Integer> arr, int k) {
// Check if 'k' is valid
if (k > arr.size())
return -1;
// Create array to store cumulative sum
int[] csum = new int[arr.size()];
csum[0] = arr.get(0);
for (int i = 1; i < arr.size(); i++)
csum[i] = csum[i - 1] + arr.get(i);
// Initialize max_sum as sum of first subarray
int max_sum = csum[k - 1];
int max_end = k - 1;
// Find sum of other subarrays and update max_sum if required
for (int i = k; i < arr.size(); i++) {
int curr_sum = csum[i] - csum[i - k];
if (curr_sum > max_sum) {
max_sum = curr_sum;
max_end = i;
}
}
// Return starting index
return max_end - k + 1;
}
public static void main(String[] args) {
List<Integer> arr = Arrays.asList(1, 12, -5, -6, 50, 3);
int k = 4;
Solution ob = new Solution();
int ans = ob.findMaxAverage(arr, k);
System.out.println("The maximum average subarray of length " + k + " begins at index " + ans);
}
}
# Python program to find beginning index of maximum average subarray using prefix sum
# Returns beginning index of maximum average subarray of length 'k'
def findMaxAverage(arr, k):
# Check if 'k' is valid
if k > len(arr):
return -1
# Create list to store cumulative sum
# csum[i] stores sum of arr[0] to arr[i]
csum = [0] * len(arr)
csum[0] = arr[0]
for i in range(1, len(arr)):
csum[i] = csum[i - 1] + arr[i]
# Initialize max_sum as sum of first subarray
max_sum = csum[k - 1]
max_end = k - 1
# Find sum of other subarrays and update max_sum if required
for i in range(k, len(arr)):
curr_sum = csum[i] - csum[i - k]
if curr_sum > max_sum:
max_sum = curr_sum
max_end = i
# Return starting index
return max_end - k + 1
# Driver program
if __name__ == "__main__":
arr = [1, 12, -5, -6, 50, 3]
k = 4
print(f"The maximum average subarray of length {k} begins at index {findMaxAverage(arr, k)}")
using System;
using System.Collections.Generic;
class GFG {
// Returns beginning index of maximum average
// subarray of length 'k'
static int findMaxAverage(List<int> arr, int k)
{
// Check if 'k' is valid
if (k > arr.Count)
return -1;
// Create and fill list to store cumulative
// sum. csum[i] stores sum of arr[0] to arr[i]
List<int> csum = new List<int>();
csum.Add(arr[0]);
for (int i = 1; i < arr.Count; i++)
{
csum.Add(csum[i - 1] + arr[i]);
}
// Initialize max_sum as sum of first subarray
int max_sum = csum[k - 1];
int max_end = k - 1;
// Find sum of other subarrays and update
// max_sum if required
for (int i = k; i < arr.Count; i++)
{
int curr_sum = csum[i] - csum[i - k];
if (curr_sum > max_sum)
{
max_sum = curr_sum;
max_end = i;
}
}
// Return starting index
return max_end - k + 1;
}
// Driver program
static void Main()
{
List<int> arr = new List<int>()
{
1, 12, -5, -6, 50, 3
};
int k = 4;
Console.WriteLine(
"The maximum average subarray of length "
+ k + " begins at index "
+ findMaxAverage(arr, k));
}
}
// Returns beginning index of maximum average
// subarray of length 'k'
function findMaxAverage(arr, k)
{
// Check if 'k' is valid
if (k > arr.length)
return -1;
// Create and fill array to store cumulative
// sum. csum[i] stores sum of arr[0] to arr[i]
let csum = new Array(arr.length);
csum[0] = arr[0];
for (let i = 1; i < arr.length; i++)
{
csum[i] = csum[i - 1] + arr[i];
}
// Initialize max_sum as sum of first subarray
let max_sum = csum[k - 1];
let max_end = k - 1;
// Find sum of other subarrays and update
// max_sum if required
for (let i = k; i < arr.length; i++)
{
let curr_sum = csum[i] - csum[i - k];
if (curr_sum > max_sum)
{
max_sum = curr_sum;
max_end = i;
}
}
// Return starting index
return max_end - k + 1;
}
// Driver program
let arr = [1, 12, -5, -6, 50, 3];
let k = 4;
console.log(
"The maximum average subarray of length "
+ k + " begins at index "
+ findMaxAverage(arr, k)
);
Output
The maximum average subarray of length 4 begins at index 1
[Expected Approach] Using Sliding Window – O(n) Time and O(1) Space
The idea is to maintain the sum of the current subarray of length
kusing a sliding window. Instead of recalculating the sum for every subarray, we subtract the element leaving the window and add the new incoming element. This allows us to efficiently track the maximum sum subarray of sizek, which directly corresponds to the maximum average subarray.
- Compute the sum of the first window of size
k - Store it as the current maximum sum
- Slide the window by adding the next element and removing the previous one
- Update maximum sum and starting index whenever a larger sum is found
#include<bits/stdc++.h>
using namespace std;
// Returns beginning index of maximum average
// subarray of length 'k'
int findMaxAverage(vector<int>& arr, int k)
{
// Check if 'k' is valid
if (k > arr.size())
return -1;
// Compute sum of first 'k' elements
int sum = arr[0];
for (int i = 1; i < k; i++)
sum += arr[i];
int max_sum = sum;
int max_end = k - 1;
// Compute sum of remaining subarrays
for (int i = k; i < arr.size(); i++)
{
sum = sum + arr[i] - arr[i - k];
if (sum > max_sum)
{
max_sum = sum;
max_end = i;
}
}
// Return starting index
return max_end - k + 1;
}
// Driver program
int main()
{
vector<int> arr = {1, 12, -5, -6, 50, 3};
int k = 4;
cout << "The maximum average subarray of "
<< "length " << k << " begins at index "
<< findMaxAverage(arr, k);
return 0;
}
import java.util.*;
class Solution {
int findMaxAverage(List<Integer> arr, int k) {
if (k > arr.size())
return -1;
int sum = 0;
// First window
for (int i = 0; i < k; i++) {
sum += arr.get(i);
}
int maxSum = sum;
int startIndex = 0;
// Sliding window
for (int i = k; i < arr.size(); i++) {
sum = sum + arr.get(i) - arr.get(i - k);
if (sum > maxSum) {
maxSum = sum;
startIndex = i - k + 1;
}
}
return startIndex;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
List<Integer> arr = new ArrayList<>();
for (int i = 0; i < n; i++) {
arr.add(sc.nextInt());
}
int k = sc.nextInt();
Solution ob = new Solution();
int ans = ob.findMaxAverage(arr, k);
System.out.println(ans);
sc.close();
}
}
# Returns beginning index of maximum average
# subarray of length 'k'
def findMaxAverage(arr, k):
# Check if 'k' is valid
if k > len(arr):
return -1
# Compute sum of first 'k' elements
total = arr[0]
for i in range(1, k):
total += arr[i]
max_sum = total
max_end = k - 1
# Compute sum of remaining subarrays
for i in range(k, len(arr)):
total = total + arr[i] - arr[i - k]
if total > max_sum:
max_sum = total
max_end = i
# Return starting index
return max_end - k + 1
# Driver program
arr = [1, 12, -5, -6, 50, 3]
k = 4
print("The maximum average subarray of "
"length", k, "begins at index",
findMaxAverage(arr, k))
using System;
using System.Collections.Generic;
class GFG {
// Returns beginning index of maximum average
// subarray of length 'k'
static int findMaxAverage(List<int> arr, int k)
{
// Check if 'k' is valid
if (k > arr.Count)
return -1;
// Compute sum of first 'k' elements
int sum = arr[0];
for (int i = 1; i < k; i++)
sum += arr[i];
int max_sum = sum;
int max_end = k - 1;
// Compute sum of remaining subarrays
for (int i = k; i < arr.Count; i++)
{
sum = sum + arr[i] - arr[i - k];
if (sum > max_sum)
{
max_sum = sum;
max_end = i;
}
}
// Return starting index
return max_end - k + 1;
}
// Driver program
static void Main()
{
List<int> arr = new List<int>()
{
1, 12, -5, -6, 50, 3
};
int k = 4;
Console.WriteLine(
"The maximum average subarray of "
+ "length " + k + " begins at index "
+ findMaxAverage(arr, k));
}
}
// Returns beginning index of maximum average
// subarray of length 'k'
function findMaxAverage(arr, k)
{
// Check if 'k' is valid
if (k > arr.length)
return -1;
// Compute sum of first 'k' elements
let sum = arr[0];
for (let i = 1; i < k; i++)
sum += arr[i];
let max_sum = sum;
let max_end = k - 1;
// Compute sum of remaining subarrays
for (let i = k; i < arr.length; i++)
{
sum = sum + arr[i] - arr[i - k];
if (sum > max_sum)
{
max_sum = sum;
max_end = i;
}
}
// Return starting index
return max_end - k + 1;
}
// Driver program
let arr = [1, 12, -5, -6, 50, 3];
let k = 4;
console.log(
"The maximum average subarray of "
+ "length " + k + " begins at index "
+ findMaxAverage(arr, k)
);
Output
The maximum average subarray of length 4 begins at index 1