 GFG App
Open App Browser
Continue

# Longest subarray having average greater than or equal to x

Given an array of integers and an integer x. Find the length of maximum size subarray having an average of integers greater than or equal to x.

Examples:

```Input : arr[] = {-2, 1, 6, -3}, x = 3
Output : 2
Longest subarray is {1, 6} having average
3.5 greater than x = 3.

Input : arr[] = {2, -3, 3, 2, 1}, x = 2
Output : 3
Longest subarray is {3, 2, 1} having
average 2 equal to x = 2.```

A simple solution is to one by one consider each subarray and find its average. If average is greater than or equal to x, then compare length of subarray with maximum length found so far. Time complexity of this solution is O(n2).

An efficient solution is to use binary search and prefix sum. Let the required Longest subarray be arr[i..j] and its length is l = j-i+1. Thus, mathematically it can be written as:

(Σ (arr[i..j]) / l ) ≥ x
==> (Σ (arr[i..j]) / l) – x ≥ 0
==> (Σ (arr[i..j]) – x*l) / l ≥ 0 …(1)

The equation (1) is equivalent to subtracting x from each element of subarray and then taking average of resultant subarray. So the resultant subarray can be obtained by subtracting x from each element of array. Let the updated subarray is arr1. Equation (1) can be further simplified as:

Σ (arr1[i..j]) / l ≥ 0
==> Σ (arr1[i..j]) ≥ 0 …(2)

Equation (2) is simply Longest subarray having sum greater than or equal to zero. The Longest subarray having sum greater than or equal to zero can be found by method discussed in following article:
Longest subarray having sum greater than k.

The step wise algo is:

1. Subtract x from each element of array.
2. Find Longest subarray having sum greater than or equal to zero in updated array using prefix sum and binary search.

Implementation:

## C++

 `// CPP program to find Longest subarray` `// having average greater than or equal` `// to x.` `#include `   `using` `namespace` `std;`   `// Comparison function used to sort preSum vector.` `bool` `compare(``const` `pair<``int``, ``int``>& a, ``const` `pair<``int``, ``int``>& b)` `{` `    ``if` `(a.first == b.first)` `        ``return` `a.second < b.second;`   `    ``return` `a.first < b.first;` `}`   `// Function to find index in preSum vector upto which` `// all prefix sum values are less than or equal to val.` `int` `findInd(vector >& preSum, ``int` `n, ``int` `val)` `{`   `    ``// Starting and ending index of search space.` `    ``int` `l = 0;` `    ``int` `h = n - 1;` `    ``int` `mid;`   `    ``// To store required index value.` `    ``int` `ans = -1;`   `    ``// If middle value is less than or equal to` `    ``// val then index can lie in mid+1..n` `    ``// else it lies in 0..mid-1.` `    ``while` `(l <= h) {` `        ``mid = (l + h) / 2;` `        ``if` `(preSum[mid].first <= val) {` `            ``ans = mid;` `            ``l = mid + 1;` `        ``}` `        ``else` `            ``h = mid - 1;` `    ``}`   `    ``return` `ans;` `}`   `// Function to find Longest subarray having average` `// greater than or equal to x.` `int` `LongestSub(``int` `arr[], ``int` `n, ``int` `x)` `{` `    ``int` `i;`   `    ``// Update array by subtracting x from` `    ``// each element.` `    ``for` `(i = 0; i < n; i++)` `        ``arr[i] -= x;`   `    ``// Length of Longest subarray.` `    ``int` `maxlen = 0;`   `    ``// Vector to store pair of prefix sum` `    ``// and corresponding ending index value.` `    ``vector > preSum;`   `    ``// To store current value of prefix sum.` `    ``int` `sum = 0;`   `    ``// To store minimum index value in range` `    ``// 0..i of preSum vector.` `    ``int` `minInd[n];`   `    ``// Insert values in preSum vector.` `    ``for` `(i = 0; i < n; i++) {` `        ``sum = sum + arr[i];` `        ``preSum.push_back({ sum, i });` `    ``}`   `    ``sort(preSum.begin(), preSum.end(), compare);`   `    ``// Update minInd array.` `    ``minInd = preSum.second;`   `    ``for` `(i = 1; i < n; i++) {` `        ``minInd[i] = min(minInd[i - 1], preSum[i].second);` `    ``}`   `    ``sum = 0;` `    ``for` `(i = 0; i < n; i++) {` `        ``sum = sum + arr[i];`   `        ``// If sum is greater than or equal to 0,` `        ``// then answer is i+1.` `        ``if` `(sum >= 0)` `            ``maxlen = i + 1;`   `        ``// If sum is less than 0, then find if` `        ``// there is a prefix array having sum` `        ``// that needs to be added to current sum to` `        ``// make its value greater than or equal to 0.` `        ``// If yes, then compare length of updated` `        ``// subarray with maximum length found so far.` `        ``else` `{` `            ``int` `ind = findInd(preSum, n, sum);` `            ``if` `(ind != -1 && minInd[ind] < i)` `                ``maxlen = max(maxlen, i - minInd[ind]);` `        ``}` `    ``}`   `    ``return` `maxlen;` `}`   `// Driver code.` `int` `main()` `{` `    ``int` `arr[] = { -2, 1, 6, -3 };` `    ``int` `n = ``sizeof``(arr) / ``sizeof``(arr);`   `    ``int` `x = 3;`   `    ``cout << LongestSub(arr, n, x);` `    ``return` `0;` `}`

## Java

 `// Java program to find Longest subarray` `// having average greater than or equal` `// to x.` `import` `java.util.*;`   `// User defined Pair class` `class` `Pair ``implements` `Comparable` `{` `    ``public` `int` `first, second;` `    ``public` `Pair(``int` `a, ``int` `b)` `    ``{` `        ``first = a;` `        ``second = b;` `    ``}`   `    ``// Method to implement Sort for` `    ``// Pair objects` `    ``@Override` `    ``public` `int` `compareTo(Pair other)` `    ``{`   `        ``if` `(``this``.first == other.first)` `            ``return` `this``.second - other.second;`   `        ``return` `this``.first - other.first;`   `    ``}` `}`   `class` `GFG` `{`   `  ``// Function to find index in preSum vector upto which` `  ``// all prefix sum values are less than or equal to val.` `  ``static` `int` `findInd(ArrayList preSum, ``int` `n, ``int` `val)` `  ``{`   `    ``// Starting and ending index of search space.` `    ``int` `l = ``0``;` `    ``int` `h = n - ``1``;` `    ``int` `mid;`   `    ``// To store required index value.` `    ``int` `ans = -``1``;`   `    ``// If middle value is less than or equal to` `    ``// val then index can lie in mid+1..n` `    ``// else it lies in 0..mid-1.` `    ``while` `(l <= h) {` `      ``mid = (l + h) / ``2``;` `      ``if` `(preSum.get(mid).first <= val) {` `        ``ans = mid;` `        ``l = mid + ``1``;` `      ``}` `      ``else` `        ``h = mid - ``1``;` `    ``}`   `    ``return` `ans;` `  ``}`   `  ``// Function to find Longest subarray having average` `  ``// greater than or equal to x.` `  ``static` `int` `LongestSub(``int``[] arr, ``int` `n, ``int` `x)` `  ``{` `    ``int` `i;`   `    ``// Update array by subtracting x from` `    ``// each element.` `    ``for` `(i = ``0``; i < n; i++)` `      ``arr[i] -= x;`   `    ``// Length of Longest subarray.` `    ``int` `maxlen = ``0``;`   `    ``// Vector to store pair of prefix sum` `    ``// and corresponding ending index value.` `    ``ArrayList preSum = ``new` `ArrayList();`   `    ``// To store current value of prefix sum.` `    ``int` `sum = ``0``;`   `    ``// To store minimum index value in range` `    ``// 0..i of preSum vector.` `    ``int``[] minInd = ``new` `int``[n];`   `    ``// Insert values in preSum vector.` `    ``for` `(i = ``0``; i < n; i++) {` `      ``sum = sum + arr[i];` `      ``preSum.add(``new` `Pair(sum, i));` `    ``}`   `    ``Collections.sort(preSum);`   `    ``// Update minInd array.` `    ``minInd[``0``] = preSum.get(``0``).second;`   `    ``for` `(i = ``1``; i < n; i++) {` `      ``minInd[i] = Math.min(minInd[i - ``1``], preSum.get(i).second);` `    ``}`   `    ``sum = ``0``;` `    ``for` `(i = ``0``; i < n; i++) {` `      ``sum = sum + arr[i];`   `      ``// If sum is greater than or equal to 0,` `      ``// then answer is i+1.` `      ``if` `(sum >= ``0``)` `        ``maxlen = i + ``1``;`   `      ``// If sum is less than 0, then find if` `      ``// there is a prefix array having sum` `      ``// that needs to be added to current sum to` `      ``// make its value greater than or equal to 0.` `      ``// If yes, then compare length of updated` `      ``// subarray with maximum length found so far.` `      ``else` `{` `        ``int` `ind = findInd(preSum, n, sum);` `        ``if` `(ind != -``1` `&& minInd[ind] < i)` `          ``maxlen = Math.max(maxlen, i - minInd[ind]);` `      ``}` `    ``}`   `    ``return` `maxlen;` `  ``}`   `  ``// Driver code.` `  ``public` `static` `void` `main(String[] args)` `  ``{` `    ``int``[] arr = { -``2``, ``1``, ``6``, -``3` `};` `    ``int` `n = arr.length;`   `    ``int` `x = ``3``;`   `    ``System.out.println(LongestSub(arr, n, x));` `  ``}` `}`   `// This code is contributed by phasing17`

## Python3

 `# Python3 program to find longest subarray ` `# having average greater than or equal to x `   `# Function to find index in preSum list of` `# tuples upto which all prefix sum values ` `# are less than or equal to val. ` `def` `findInd(preSum, n, val):` `    `  `    ``# Starting and ending index ` `    ``# of search space. ` `    ``l ``=` `0` `    ``h ``=` `n ``-` `1` `    `  `    ``# To store required index value` `    ``ans ``=` `-``1` `    `  `    ``# If middle value is less than or ` `    ``# equal to val then index can ` `    ``# lie in mid+1..n else it lies` `    ``# in 0..mid-1` `    ``while` `(l <``=` `h):` `        ``mid ``=` `(l ``+` `h) ``/``/` `2` `        ``if` `preSum[mid][``0``] <``=` `val:` `            ``ans ``=` `mid` `            ``l ``=` `mid ``+` `1` `        ``else``:` `            ``h ``=` `mid ``-` `1` `            `  `    ``return` `ans`   `# Function to find Longest subarray` `# having average greater than or ` `# equal to x. ` `def` `LongestSub(arr, n, x):` `    `  `    ``# Update array by subtracting` `    ``# x from each element` `    ``for` `i ``in` `range``(n):` `        ``arr[i] ``-``=` `x` `        `  `    ``# Length of Longest subarray. ` `    ``maxlen ``=` `0` `    `  `    ``# To store current value of ` `    ``# prefix sum. ` `    ``total ``=` `0` `    `  `    ``# To store minimum index value in` `    ``# range 0..i of preSum vector.` `    ``minInd ``=` `[``None``] ``*` `n` `    `  `    ``# list to store pair of prefix sum ` `    ``# and corresponding ending index value. ` `    ``preSum ``=` `[]` `    `  `    ``# Insert values in preSum vector` `    ``for` `i ``in` `range``(n):` `        ``total ``+``=` `arr[i]` `        ``preSum.append((total, i))` `        `  `    ``preSum ``=` `sorted``(preSum)` `    `  `    ``# Update minInd array.` `    ``minInd[``0``] ``=` `preSum[``0``][``1``]` `    ``for` `i ``in` `range``(``1``, n):` `        ``minInd[i] ``=` `min``(minInd[i ``-` `1``], ` `                        ``preSum[i][``1``])` `    ``total ``=` `0` `    ``for` `i ``in` `range``(n):` `        ``total ``+``=` `arr[i]` `        `  `        ``# If sum is greater than or equal ` `        ``# to 0, then answer is i+1` `        ``if` `total >``=` `0``:` `            ``maxlen ``=` `i ``+` `1` `        `  `        ``# If sum is less than 0, then find if ` `        ``# there is a prefix array having sum ` `        ``# that needs to be added to current sum to ` `        ``# make its value greater than or equal to 0. ` `        ``# If yes, then compare length of updated ` `        ``# subarray with maximum length found so far` `        ``else``:` `            ``ind ``=` `findInd(preSum, n, total)` `            ``if` `(ind !``=` `-``1``) & (minInd[ind] < i):` `                ``maxlen ``=` `max``(maxlen, i ``-` `minInd[ind])` `                `  `    ``return` `maxlen`   `# Driver Code` `if` `__name__ ``=``=` `'__main__'``:` `    `  `    ``arr ``=` `[ ``-``2``, ``1``, ``6``, ``-``3` `]` `    ``n ``=` `len``(arr)` `    ``x ``=` `3` `    `  `    ``print``(LongestSub(arr, n, x))`   `# This code is contributed by Vikas Chitturi`

## C#

 `// C# program to find Longest subarray` `// having average greater than or equal` `// to x.` `using` `System;` `using` `System.Collections.Generic;`     `// User defined Pair class` `class` `Pair : IComparable` `{` `    ``public` `int` `first, second;` `    ``public` `Pair(``int` `a, ``int` `b)` `    ``{` `        ``first = a;` `        ``second = b;` `    ``}`   `    ``// Method to implement Sort for` `    ``// Pair objects` `    ``public` `int` `CompareTo(Pair other)` `    ``{`   `        ``if` `(``this``.first == other.first)` `            ``return` `this``.second - other.second;`   `        ``return` `this``.first - other.first;`   `    ``}` `}`   `class` `GFG` `{`   `  ``// Function to find index in preSum vector upto which` `  ``// all prefix sum values are less than or equal to val.` `  ``static` `int` `findInd(List preSum, ``int` `n, ``int` `val)` `  ``{`   `    ``// Starting and ending index of search space.` `    ``int` `l = 0;` `    ``int` `h = n - 1;` `    ``int` `mid;`   `    ``// To store required index value.` `    ``int` `ans = -1;`   `    ``// If middle value is less than or equal to` `    ``// val then index can lie in mid+1..n` `    ``// else it lies in 0..mid-1.` `    ``while` `(l <= h) {` `      ``mid = (l + h) / 2;` `      ``if` `(preSum[mid].first <= val) {` `        ``ans = mid;` `        ``l = mid + 1;` `      ``}` `      ``else` `        ``h = mid - 1;` `    ``}`   `    ``return` `ans;` `  ``}`   `  ``// Function to find Longest subarray having average` `  ``// greater than or equal to x.` `  ``static` `int` `LongestSub(``int``[] arr, ``int` `n, ``int` `x)` `  ``{` `    ``int` `i;`   `    ``// Update array by subtracting x from` `    ``// each element.` `    ``for` `(i = 0; i < n; i++)` `      ``arr[i] -= x;`   `    ``// Length of Longest subarray.` `    ``int` `maxlen = 0;`   `    ``// Vector to store pair of prefix sum` `    ``// and corresponding ending index value.` `    ``List preSum = ``new` `List();`   `    ``// To store current value of prefix sum.` `    ``int` `sum = 0;`   `    ``// To store minimum index value in range` `    ``// 0..i of preSum vector.` `    ``int``[] minInd = ``new` `int``[n];`   `    ``// Insert values in preSum vector.` `    ``for` `(i = 0; i < n; i++) {` `      ``sum = sum + arr[i];` `      ``preSum.Add(``new` `Pair(sum, i));` `    ``}`   `    ``preSum.Sort();`   `    ``// Update minInd array.` `    ``minInd = preSum.second;`   `    ``for` `(i = 1; i < n; i++) {` `      ``minInd[i] = Math.Min(minInd[i - 1], preSum[i].second);` `    ``}`   `    ``sum = 0;` `    ``for` `(i = 0; i < n; i++) {` `      ``sum = sum + arr[i];`   `      ``// If sum is greater than or equal to 0,` `      ``// then answer is i+1.` `      ``if` `(sum >= 0)` `        ``maxlen = i + 1;`   `      ``// If sum is less than 0, then find if` `      ``// there is a prefix array having sum` `      ``// that needs to be added to current sum to` `      ``// make its value greater than or equal to 0.` `      ``// If yes, then compare length of updated` `      ``// subarray with maximum length found so far.` `      ``else` `{` `        ``int` `ind = findInd(preSum, n, sum);` `        ``if` `(ind != -1 && minInd[ind] < i)` `          ``maxlen = Math.Max(maxlen, i - minInd[ind]);` `      ``}` `    ``}`   `    ``return` `maxlen;` `  ``}`   `  ``// Driver code.` `  ``public` `static` `void` `Main(``string``[] args)` `  ``{` `    ``int``[] arr = { -2, 1, 6, -3 };` `    ``int` `n = arr.Length;`   `    ``int` `x = 3;`   `    ``Console.WriteLine(LongestSub(arr, n, x));` `  ``}` `}`   `// This code is contributed by phasing17`

## Javascript

 ``

Output

`2`

Complexity Analysis:

• Time Complexity: O(nlogn)
• Auxiliary Space: O(n)

My Personal Notes arrow_drop_up