Given an integer array arr[] and an integer k. Find the contiguous subarray of size k that has the minimum average value among all possible subarrays of size k. Return position (or index + 1) of the first element of that subarray.
Examples :
Input: arr[] = [30, 20, 10], k = 1
Output: 3
Explanation: Subarrays of length 1 are {30}, {20} and {10}. {10} has the least average equal to 10.Input: arr[] = [30, 20, 10], k = 2
Output: 2
Explanation: Subarrays of length 2 are {30, 20} and {20, 10}. {20, 10} has the least average equal to (20 + 10)/2 = 15.
Table of Content
[Naive Approach] By Generating All Subarrays - O(n * k) Time and O(1) Space
The idea is to generate all subarrays of size k one by one and find their averages. Among all the averages, find the subarray with minimum average and return its starting index.
Trick: We can find sum of all subarrays instead of averages because each subarray is of size k so, subarray with minimum sum will have least average.
- Initialize minSum as a very large value and minIndex = 0.
- Generate all possible contiguous subarrays of size k.
- Compute the sum of each subarray and compare it with minSum.
- If a smaller sum is found, update minSum and store its starting index.
- Finally return minIndex + 1 (1-based position) as answer.
#include <climits>
#include <iostream>
#include <vector>
using namespace std;
int leastAvg(vector<int> &arr, int k)
{
int n = arr.size();
int minSum = INT_MAX;
int minIndex = 0;
// Generate all possible subarrays of size k
for (int i = 0; i <= n - k; i++)
{
int currentSum = 0;
// Compute sum of current subarray
for (int j = i; j < i + k; j++)
{
currentSum += arr[j];
}
// Update minimum sum and index
if (currentSum < minSum)
{
minSum = currentSum;
minIndex = i;
}
}
return minIndex + 1;
}
int main()
{
vector<int> arr = {30, 20, 10};
int k = 1;
int ans = leastAvg(arr, k);
cout << ans << endl;
return 0;
}
class GFG {
static int leastAvg(int[] arr, int k) {
int n = arr.length;
int minSum = Integer.MAX_VALUE;
int minIndex = 0;
// Generate all possible subarrays of size k
for (int i = 0; i <= n - k; i++) {
int currentSum = 0;
// Compute sum of current subarray
for (int j = i; j < i + k; j++) {
currentSum += arr[j];
}
// Update minimum sum and index
if (currentSum < minSum) {
minSum = currentSum;
minIndex = i;
}
}
return minIndex + 1;
}
public static void main(String[] args) {
int[] arr = {30, 20, 10};
int k = 1;
int ans = leastAvg(arr, k);
System.out.println(ans);
}
}
def leastAvg(arr, k):
n = len(arr)
minSum = float('inf')
minIndex = 0
# Generate all possible subarrays of size k
for i in range(n - k + 1):
currentSum = 0
# Compute sum of current subarray
for j in range(i, i + k):
currentSum += arr[j]
# Update minimum sum and index
if currentSum < minSum:
minSum = currentSum
minIndex = i
return minIndex + 1
# Driver Code
if __name__ == "__main__":
arr = [30, 20, 10]
k = 1
ans = leastAvg(arr, k)
print(ans)
using System;
class GFG
{
static int leastAvg(int[] arr, int k)
{
int n = arr.Length;
int minSum = int.MaxValue;
int minIndex = 0;
// Generate all possible subarrays of size k
for (int i = 0; i <= n - k; i++)
{
int currentSum = 0;
// Compute sum of current subarray
for (int j = i; j < i + k; j++)
{
currentSum += arr[j];
}
// Update minimum sum and index
if (currentSum < minSum)
{
minSum = currentSum;
minIndex = i;
}
}
return minIndex + 1;
}
static void Main()
{
int[] arr = { 30, 20, 10 };
int k = 1;
int ans = leastAvg(arr, k);
Console.WriteLine(ans);
}
}
function leastAvg(arr, k) {
let n = arr.length;
let minSum = Number.MAX_SAFE_INTEGER;
let minIndex = 0;
// Generate all possible subarrays of size k
for (let i = 0; i <= n - k; i++) {
let currentSum = 0;
// Compute sum of current subarray
for (let j = i; j < i + k; j++) {
currentSum += arr[j];
}
// Update minimum sum and index
if (currentSum < minSum) {
minSum = currentSum;
minIndex = i;
}
}
return minIndex + 1;
}
// Driver Code
let arr = [ 30, 20, 10 ];
let k = 1;
let ans = leastAvg(arr, k);
console.log(ans);
Output
3
[Expected Approach] Using Sliding Window - O(n) Time and O(1) Space
The idea is to avoid recalculating the sum for every subarray from scratch. We compute the first window sum once and then slide the window by removing the leftmost element and adding the next element.
- Calculate the sum of the first window of size k.
- Initialize mini with the first window sum and idx = 1 (starting position).
- Traverse the remaining elements from index k to n-1.
- Slide the window by removing the leftmost element and adding the new element.
- Compare the current window sum with mini.
- If a smaller sum is found, update mini and store its starting position in idx; finally return idx.
#include <iostream>
#include <vector>
using namespace std;
int leastAvg(vector<int> &arr, int k)
{
int n = arr.size();
int sum = 0;
// Calculate sum of first window of size k
for (int i = 0; i < k; i++)
{
sum += arr[i];
}
// Initialize minimum sum with first window sum
int mini = sum;
// Store 1-based starting index
int idx = 1;
// Slide the window
for (int i = k; i < n; i++)
{
// Remove leftmost element and add new element
sum += arr[i] - arr[i - k];
// Update minimum sum and starting index
if (sum < mini)
{
mini = sum;
idx = i - k + 2;
}
}
return idx;
}
int main()
{
vector<int> arr = {30, 20, 10};
int k = 1;
int ans = leastAvg(arr, k);
cout << ans << endl;
return 0;
}
class GFG {
static int leastAvg(int[] arr, int k) {
int n = arr.length;
int sum = 0;
// Calculate sum of first window of size k
for (int i = 0; i < k; i++) {
sum += arr[i];
}
// Initialize minimum sum with first window sum
int mini = sum;
// Store 1-based starting index
int idx = 1;
// Slide the window
for (int i = k; i < n; i++) {
// Remove leftmost element and add new element
sum += arr[i] - arr[i - k];
// Update minimum sum and starting index
if (sum < mini) {
mini = sum;
idx = i - k + 2;
}
}
return idx;
}
public static void main(String[] args) {
int[] arr = {30, 20, 10};
int k = 1;
int ans = leastAvg(arr, k);
System.out.println(ans);
}
}
def leastAvg(arr, k):
n = len(arr)
sum = 0
# Calculate sum of first window of size k
for i in range(k):
sum += arr[i]
# Initialize minimum sum with first window sum
mini = sum
# Store 1-based starting index
idx = 1
# Slide the window
for i in range(k, n):
# Remove leftmost element and add new element
sum += arr[i] - arr[i - k]
# Update minimum sum and starting index
if sum < mini:
mini = sum
idx = i - k + 2
return idx
# Driver Code
if __name__ == "__main__":
arr = [30, 20, 10]
k = 1
ans = leastAvg(arr, k)
print(ans)
using System;
class GFG
{
static int leastAvg(int[] arr, int k)
{
int n = arr.Length;
int sum = 0;
// Calculate sum of first window of size k
for (int i = 0; i < k; i++)
{
sum += arr[i];
}
// Initialize minimum sum with first window sum
int mini = sum;
// Store 1-based starting index
int idx = 1;
// Slide the window
for (int i = k; i < n; i++)
{
// Remove leftmost element and add new element
sum += arr[i] - arr[i - k];
// Update minimum sum and starting index
if (sum < mini)
{
mini = sum;
idx = i - k + 2;
}
}
return idx;
}
static void Main()
{
int[] arr = { 30, 20, 10 };
int k = 1;
int ans = leastAvg(arr, k);
Console.WriteLine(ans);
}
}
function leastAvg(arr, k)
{
let n = arr.length;
let sum = 0;
// Calculate sum of first window of size k
for (let i = 0; i < k; i++) {
sum += arr[i];
}
// Initialize minimum sum with first window sum
let mini = sum;
// Store 1-based starting index
let idx = 1;
// Slide the window
for (let i = k; i < n; i++) {
// Remove leftmost element and add new element
sum += arr[i] - arr[i - k];
// Update minimum sum and starting index
if (sum < mini) {
mini = sum;
idx = i - k + 2;
}
}
return idx;
}
// Driver Code
let arr = [ 30, 20, 10 ];
let k = 1;
let ans = leastAvg(arr, k);
console.log(ans);
Output
3