Given an array of N integers. The task is to find the longest contiguous subarray so that the average of its elements is greater than or equal to a given number X.
Examples:
Input: arr = {1, 1, 2, -1, -1, 1}, X = 1
Output: 3
Length of longest subarray
with average >= 1 is 3 i.e.
((1+1+2)/3)= 1.333
Input: arr[] = {2, -3, 3, 2, 1}, x = 2
Output: 3
Length of Longest subarray is 3 having
average 2 which is equal to x.
An approach with time complexity O(Nlogn) has been already discussed here. In this post, an efficient approach with time complexity O(N) will be discussed.
Approach:
- Subtract X from each arr[i] and convert the array into prefix array. Lets call the new array as prefixarr[].
- Now the problem becomes finding max(j-i) in prefixarr[] such that j > i and prefixarr[j] > prefixarr[i] i.e. similar to Given an array arr[], find the maximum j – i such that arr[j] > arr[i]
Below is the implementation of above approach:
C++
// C++ implementation of above approach#include <bits/stdc++.h>using namespace std;// Utility Function to find the index// with maximum differenceint maxIndexDiff(int arr[], int n){ int maxDiff; int i, j; int LMin[n], RMax[n]; // Construct LMin[] such that LMin[i] // stores the minimum value // from (arr[0], arr[1], ... arr[i]) LMin[0] = arr[0]; for (i = 1; i < n; ++i) LMin[i] = min(arr[i], LMin[i - 1]); // Construct RMax[] such that RMax[j] // stores the maximum value // from (arr[j], arr[j+1], ..arr[n-1]) RMax[n - 1] = arr[n - 1]; for (j = n - 2; j >= 0; --j) RMax[j] = max(arr[j], RMax[j + 1]); // Traverse both arrays from left to right // to find optimum j - i // This process is similar to merge() // of MergeSort i = 0, j = 0, maxDiff = -1; while (j < n && i < n) { if (LMin[i] < RMax[j]) { maxDiff = max(maxDiff, j - i); j = j + 1; } else i = i + 1; } return maxDiff + 1;}// utility Function which subtracts X from all// the elements in the arrayvoid modifyarr(int arr[], int n, int x){ for (int i = 0; i < n; i++) arr[i] = arr[i] - x;}// Calculating the prefix sum array// of the modified arrayvoid calcprefix(int arr[], int n){ int s = 0; for (int i = 0; i < n; i++) { s += arr[i]; arr[i] = s; }}// Function to find the length of the longest// subarray with average >= xint longestsubarray(int arr[], int n, int x){ modifyarr(arr, n, x); calcprefix(arr, n); return maxIndexDiff(arr, n);}// Driver codeint main(){ int arr[] = { 1, 1, 2, -1, -1, 1 }; int x = 1; int n = sizeof(arr) / sizeof(int); cout << longestsubarray(arr, n, x) << endl; return 0;} |
Java
// Java implementation of // above approachimport java.io.*;import java.lang.*;class GFG{ // Utility Function to find the// index with maximum differencestatic int maxIndexDiff(int arr[], int n){ int maxDiff; int i, j; int LMin[], RMax[]; LMin = new int[n]; RMax = new int[n]; // Construct LMin[] such that // LMin[i] stores the minimum value // from (arr[0], arr[1], ... arr[i]) LMin[0] = arr[0]; for (i = 1; i < n; ++i) LMin[i] = Math.min(arr[i], LMin[i - 1]); // Construct RMax[] such that // RMax[j] stores the maximum value // from (arr[j], arr[j+1], ..arr[n-1]) RMax[n - 1] = arr[n - 1]; for (j = n - 2; j >= 0; --j) RMax[j] = Math.max(arr[j], RMax[j + 1]); // Traverse both arrays from left // to right to find optimum j - i // This process is similar to merge() // of MergeSort i = 0; j = 0; maxDiff = -1; while (j < n && i < n) { if (LMin[i] < RMax[j]) { maxDiff = Math.max(maxDiff, j - i); j = j + 1; } else i = i + 1; } return (maxDiff + 1);}// utility Function which subtracts X // from all the elements in the arraystatic void modifyarr(int arr[], int n, int x){ for (int i = 0; i < n; i++) arr[i] = arr[i] - x;}// Calculating the prefix sum // array of the modified arraystatic void calcprefix(int arr[], int n){ int s = 0; for (int i = 0; i < n; i++) { s += arr[i]; arr[i] = s; }}// Function to find the length of the // longest subarray with average >= xstatic int longestsubarray(int arr[], int n, int x){ modifyarr(arr, n, x); calcprefix(arr, n); return maxIndexDiff(arr, n);}// Driver codepublic static void main(String args[]){ int[] arr ={ 1, 1, 2, -1, -1, 1 }; int x = 1; int n = arr.length; System.out.println(longestsubarray(arr, n, x));}}// This code is contributed by Subhadeep |
Python 3
# Python 3 implementation # of above approach# Utility Function to find the # index with maximum differencedef maxIndexDiff(arr,n): LMin = [None] * n RMax = [None] * n # Construct LMin[] such that LMin[i] # stores the minimum value # from (arr[0], arr[1], ... arr[i]) LMin[0] = arr[0] for i in range(1, n): LMin[i] = min(arr[i], LMin[i - 1]) # Construct RMax[] such that RMax[j] # stores the maximum value # from (arr[j], arr[j+1], ..arr[n-1]) RMax[n - 1] = arr[n - 1] for j in range(n - 2,-1,-1): RMax[j] = max(arr[j], RMax[j + 1]) # Traverse both arrays from left # to right to find optimum j - i # This process is similar to merge() # of MergeSort i = 0 j = 0 maxDiff = -1 while (j < n and i < n): if (LMin[i] < RMax[j]): maxDiff = max(maxDiff, j - i) j = j + 1 else: i = i + 1 return maxDiff + 1# utility Function which subtracts X # from all the elements in the arraydef modifyarr(arr, n, x): for i in range(n): arr[i] = arr[i] - x# Calculating the prefix sum # array of the modified arraydef calcprefix(arr, n): s = 0 for i in range(n): s += arr[i] arr[i] = s# Function to find the length of the# longest subarray with average >= xdef longestsubarray(arr, n, x): modifyarr(arr, n, x) calcprefix(arr, n) return maxIndexDiff(arr, n)# Driver codeif __name__ == "__main__": arr = [ 1, 1, 2, -1, -1, 1 ] x = 1 n = len(arr) print(longestsubarray(arr, n, x)) # This code is contributed by ChitraNayal |
C#
// C# implementation of // above approachusing System;class GFG{ // Utility Function to find the// index with maximum differencestatic int maxIndexDiff(int[] arr, int n){ int maxDiff; int i, j; int[] LMin = new int[n]; int[] RMax = new int[n]; // Construct LMin[] such that // LMin[i] stores the minimum value // from (arr[0], arr[1], ... arr[i]) LMin[0] = arr[0]; for (i = 1; i < n; ++i) LMin[i] = Math.Min(arr[i], LMin[i - 1]); // Construct RMax[] such that // RMax[j] stores the maximum value // from (arr[j], arr[j+1], ..arr[n-1]) RMax[n - 1] = arr[n - 1]; for (j = n - 2; j >= 0; --j) RMax[j] = Math.Max(arr[j], RMax[j + 1]); // Traverse both arrays from left // to right to find optimum j - i // This process is similar to merge() // of MergeSort i = 0; j = 0; maxDiff = -1; while (j < n && i < n) { if (LMin[i] < RMax[j]) { maxDiff = Math.Max(maxDiff, j - i); j = j + 1; } else i = i + 1; } return (maxDiff + 1);}// utility Function which subtracts X // from all the elements in the arraystatic void modifyarr(int[] arr, int n, int x){ for (int i = 0; i < n; i++) arr[i] = arr[i] - x;}// Calculating the prefix sum // array of the modified arraystatic void calcprefix(int[] arr, int n){ int s = 0; for (int i = 0; i < n; i++) { s += arr[i]; arr[i] = s; }}// Function to find the length of the // longest subarray with average >= xstatic int longestsubarray(int[] arr, int n, int x){ modifyarr(arr, n, x); calcprefix(arr, n); return maxIndexDiff(arr, n);}// Driver codepublic static void Main(){ int[] arr ={ 1, 1, 2, -1, -1, 1 }; int x = 1; int n = arr.Length; Console.Write(longestsubarray(arr, n, x));}}// This code is contributed// by ChitraNayal |
PHP
<?php // PHP implementation of above approach// Utility Function to find the // index with maximum differencefunction maxIndexDiff(&$arr, $n){ $LMin[$n] = array(); $RMax[$n] = array(); // Construct LMin[] such that LMin[i] // stores the minimum value // from (arr[0], arr[1], ... arr[i]) $LMin[0] = $arr[0]; for ($i = 1; $i < $n; ++$i) $LMin[$i] = min($arr[$i], $LMin[$i - 1]); // Construct RMax[] such that RMax[j] // stores the maximum value // from (arr[j], arr[j+1], ..arr[n-1]) $RMax[$n - 1] = $arr[$n - 1]; for ($j = $n - 2; $j >= 0; --$j) $RMax[$j] = max($arr[$j], $RMax[$j + 1]); // Traverse both arrays from left // to right to find optimum j - i // This process is similar to merge() // of MergeSort $i = 0; $j = 0; $maxDiff = -1; while ($j < $n && $i < $n) { if ($LMin[$i] < $RMax[$j]) { $maxDiff = max($maxDiff, $j - $i); $j = $j + 1; } else $i = $i + 1; } return $maxDiff + 1;}// utility Function which subtracts X// from all the elements in the arrayfunction modifyarr($arr, $n, $x){ for ($i = 0; $i < $n; $i++) $arr[$i] = $arr[$i] - $x; return calcprefix($arr, $n);}// Calculating the prefix sum // array of the modified arrayfunction calcprefix(&$arr, $n){ $s = 0; for ($i = 0; $i < $n; $i++) { $s += $arr[$i]; $arr[$i] = $s; } return maxIndexDiff($arr, $n);}// Function to find the length of the // longest subarray with average >= xfunction longestsubarray(&$arr, $n, $x){ return modifyarr($arr, $n, $x);}// Driver code$arr = array( 1, 1, 2, -1, -1, 1 );$x = 1;$n = sizeof($arr);echo longestsubarray($arr, $n, $x) ;// This code is contributed // by ChitraNayal?> |
Javascript
<script>// Javascript implementation of// above approach // Utility Function to find the// index with maximum difference function maxIndexDiff(arr,n){ let maxDiff; let i, j; let LMin, RMax; LMin = new Array(n); RMax = new Array(n); // Construct LMin[] such that // LMin[i] stores the minimum value // from (arr[0], arr[1], ... arr[i]) LMin[0] = arr[0]; for (i = 1; i < n; ++i) LMin[i] = Math.min(arr[i], LMin[i - 1]); // Construct RMax[] such that // RMax[j] stores the maximum value // from (arr[j], arr[j+1], ..arr[n-1]) RMax[n - 1] = arr[n - 1]; for (j = n - 2; j >= 0; --j) RMax[j] = Math.max(arr[j], RMax[j + 1]); // Traverse both arrays from left // to right to find optimum j - i // This process is similar to merge() // of MergeSort i = 0; j = 0; maxDiff = -1; while (j < n && i < n) { if (LMin[i] < RMax[j]) { maxDiff = Math.max(maxDiff, j - i); j = j + 1; } else i = i + 1; } return (maxDiff + 1);}// utility Function which subtracts X// from all the elements in the arrayfunction modifyarr(arr,n,x){ for (let i = 0; i < n; i++) arr[i] = arr[i] - x;}// Calculating the prefix sum// array of the modified arrayfunction calcprefix(arr,n){ let s = 0; for (let i = 0; i < n; i++) { s += arr[i]; arr[i] = s; }}// Function to find the length of the// longest subarray with average >= xfunction longestsubarray(arr,n,x){ modifyarr(arr, n, x); calcprefix(arr, n); return maxIndexDiff(arr, n);}// Driver codelet arr=[1, 1, 2, -1, -1, 1 ];let x = 1;let n = arr.length;document.write(longestsubarray(arr, n, x));// This code is contributed by avanitrachhadiya2155</script> |
3
Complexity Analysis:
- Time Complexity: O(N)
- Auxiliary Space: O(1)
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!

… [Trackback]
[…] Find More on that Topic: geeksforgeeks.org/longest-subarray-having-average-greater-than-or-equal-to-x-set-2/ […]
… [Trackback]
[…] Read More on to that Topic: geeksforgeeks.org/longest-subarray-having-average-greater-than-or-equal-to-x-set-2/ […]