Open In App

Longest subarray having average greater than or equal to x | Set-2

Improve
Improve
Like Article
Like
Save
Share
Report

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:  

  1. Subtract X from each arr[i] and convert the array into prefix array. Lets call the new array as prefixarr[].
  2. 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 difference
int 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 array
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 array
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 >= x
int longestsubarray(int arr[], int n, int x)
{
    modifyarr(arr, n, x);
    calcprefix(arr, n);
 
    return maxIndexDiff(arr, n);
}
 
// Driver code
int 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 approach
import java.io.*;
import java.lang.*;
 
class GFG
{
     
// Utility Function to find the
// index with maximum difference
static 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 array
static 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 array
static 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 >= x
static int longestsubarray(int arr[],
                           int n, int x)
{
    modifyarr(arr, n, x);
    calcprefix(arr, n);
 
    return maxIndexDiff(arr, n);
}
 
// Driver code
public 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 difference
def 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 array
def modifyarr(arr, n, x):
    for i in range(n):
        arr[i] = arr[i] - x
 
# Calculating the prefix sum
# array of the modified array
def 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 >= x
def longestsubarray(arr, n, x):
    modifyarr(arr, n, x)
    calcprefix(arr, n)
 
    return maxIndexDiff(arr, n)
 
# Driver code
if __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 approach
using System;
 
class GFG
{
     
// Utility Function to find the
// index with maximum difference
static 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 array
static 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 array
static 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 >= x
static int longestsubarray(int[] arr,
                           int n, int x)
{
    modifyarr(arr, n, x);
    calcprefix(arr, n);
 
    return maxIndexDiff(arr, n);
}
 
// Driver code
public 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 difference
function 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 array
function 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 array
function 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 >= x
function 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 array
function modifyarr(arr,n,x)
{
    for (let i = 0; i < n; i++)
        arr[i] = arr[i] - x;
}
 
// Calculating the prefix sum
// array of the modified array
function 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 >= x
function longestsubarray(arr,n,x)
{
    modifyarr(arr, n, x);
    calcprefix(arr, n);
  
    return maxIndexDiff(arr, n);
}
 
// Driver code
let 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>


Output

3

Complexity Analysis:

  • Time Complexity: O(N) 
  • Auxiliary Space: O(1)


Last Updated : 31 Aug, 2022
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads