Open In App

Break an array into maximum number of sub-arrays such that their averages are same

Improve
Improve
Like Article
Like
Save
Share
Report

Given an integer array, the task is to divide the array into the maximum number of sub-arrays such that the averages of all subarrays are the same. If it is not possible to divide, then print “Not possible”.

Examples: 

Input : arr[] = {1, 5, 7, 2, 0};
Output : (0  1) 
         (2  4) 
Subarrays arr[0..1] and arr[2..4] 
have same average.

Input  : arr[] = {4, 6, 2, 4, 8, 0, 6, 2};    
Output : (0, 0)
         (1, 2)
         (3, 3)
         (4, 5)
         (6, 7)

Input : arr[] = {3, 3, 3};
Output : (0, 0)
         (1, 1)
         (2, 2)

Input  : arr[] = {4, 3, 5, 9, 11};
Output : Not possible

The idea is based on the fact that if an array can be divided into subarrays of the same average, then the average of all these subarrays must be the same as an overall average.

  1. Find the average of the whole array. 
  2. Traverse array again and keep track of the average of the current subarray. As soon as the average becomes the same as the overall average, print the current subarray and begin a new subarray.

This solution divides into the maximum number of subarrays because we begin a new subarray as soon as we find the average same as an overall average.  

Implementation:

C++




// C++ program to break given array into maximum
// number of subarrays with equal average.
#include<bits/stdc++.h>
using namespace std;
 
void findSubarrays(int arr[], int n)
{
    // To store all points where we can break
    // given array into equal average subarrays.
    vector<int> result;
 
    // Compute total array sum
    int sum = 0;
    for (int i = 0; i < n; i++)
        sum += arr[i];
 
    int curr_sum = 0;     // Current Sum
    int prev_index = -1;  // Index of previous subarray
 
    for (int i = 0; i < n ; i++)
    {
        curr_sum += arr[i];
 
        // If current point is a break point. Note that
        // we don't compare actual averages to avoid
        // floating point errors.
        if (sum * (i - prev_index) == curr_sum * n)
        {
            // Update current sum and previous index
            curr_sum = 0;
            prev_index = i;
 
            // Add current break point
            result.push_back(i);
        }
    }
 
    // If last break point was not end of array, we
    // cannot break the whole array.
    if (prev_index != n-1)
    {
        cout << "Not Possible";
        return;
    }
 
    // Printing the result in required format
    cout << "(0, " << result[0] << ")\n";
    for (int i=1; i<result.size(); i++)
        cout << "(" << result[i-1] + 1 << ", "
             << result[i] << ")\n";
}
 
// Main Entry function code
int main()
{
    int arr[] = {4, 6, 2, 4, 8, 0, 6, 2};
    int n = sizeof(arr)/sizeof(arr[0]);
    findSubarrays(arr, n);
    return 0;
}


Java




// Java program to break given array into maximum
// number of subarrays with equal average.
import java.util.Vector;
class GFG {
 
static void findSubarrays(int arr[], int n)
{
    // To store all points where we can break
    // given array into equal average subarrays.
    Vector<Integer> result = new Vector<>();
  
    // Compute total array sum
    int sum = 0;
    for (int i = 0; i < n; i++)
        sum += arr[i];
  
    int curr_sum = 0;     // Current Sum
    int prev_index = -1// Index of previous subarray
  
    for (int i = 0; i < n ; i++)
    {
        curr_sum += arr[i];
  
        // If current point is a break point. Note that
        // we don't compare actual averages to avoid
        // floating point errors.
        if (sum *(i - prev_index) == curr_sum*n)
        {
            // Update current sum and previous index
            curr_sum = 0;
            prev_index = i;
  
            // Add current break point
            result.add(i);
        }
    }
  
    // If last break point was not end of array, we
    // cannot break the whole array.
    if (prev_index != n-1)
    {
        System.out.println("Not Possible");
        return;
    }
  
    // Printing the result in required format
    System.out.print("(0, " + result.get(0) + ")\n");
    for (int i=1; i<result.size(); i++)
        System.out.print("(" + (result.get(i-1) + 1) + ", "
             + result.get(i) + ")\n");
}
  
// Main Entry function code
 public static void main(String[] args) {
       int arr[] = {4, 6, 2, 4, 8, 0, 6, 2};
    int n = arr.length;
    findSubarrays(arr, n);
    }
}
// This code is contributed by 29AjayKumar


Python3




# Python 3 program to break given array
# into maximum number of subarrays with
# equal average.
 
def findSubarrays(arr, n):
     
    # To store all points where we can break
    # given array into equal average subarrays.
    result = []
 
    # Compute total array sum
    sum = 0
    for i in range(0, n, 1):
        sum += arr[i]
 
    curr_sum = 0    # Current Sum
    prev_index = -1 # Index of previous subarray
 
    for i in range(0, n, 1):
        curr_sum += arr[i]
 
        # If current point is a break point.
        # Note that we don't compare actual
        # averages to avoid floating point errors.
        if (sum *(i - prev_index) == curr_sum * n):
             
            # Update current sum and
            # previous index
            curr_sum = 0
            prev_index = i
 
            # Add current break point
            result.append(i)
             
    # If last break point was not end of
    # array, we cannot break the whole array.
    if (prev_index != n - 1):
        print("Not Possible", end = " ")
 
    # Printing the result in required format
    print("( 0 ,", result[0], ")")
    for i in range(1, len(result), 1):
        print("(", result[i - 1] + 1, ",",
                            result[i],")")
 
# Driver Code
if __name__ == '__main__':
    arr = [4, 6, 2, 4, 8, 0, 6, 2]
    n = len(arr)
    findSubarrays(arr, n)
 
# This code is contributed by
# Sanjit_Prasad


C#




// C# program to break given array into maximum
// number of subarrays with equal average.
using System;
using System.Collections.Generic;
 
class GFG
{
 
static void findSubarrays(int []arr, int n)
{
    // To store all points where we can break
    // given array into equal average subarrays.
    List<int> result = new List<int>();
 
    // Compute total array sum
    int sum = 0;
    for (int i = 0; i < n; i++)
        sum += arr[i];
 
    int curr_sum = 0;     // Current Sum
    int prev_index = -1; // Index of previous subarray
 
    for (int i = 0; i < n ; i++)
    {
        curr_sum += arr[i];
 
        // If current point is a break point. Note that
        // we don't compare actual averages to avoid
        // floating point errors.
        if (sum *(i - prev_index) == curr_sum*n)
        {
            // Update current sum and previous index
            curr_sum = 0;
            prev_index = i;
 
            // Add current break point
            result.Add(i);
        }
    }
 
    // If last break point was not end of array, we
    // cannot break the whole array.
    if (prev_index != n-1)
    {
        Console.Write("Not Possible");
        return;
    }
 
    // Printing the result in required format
    Console.Write("(0, " + result[0] + ")\n");
    for (int i = 1; i < result.Count; i++)
        Console.Write("(" + (result[i-1] + 1) + ", "
            + result[i] + ")\n");
}
 
// Driver code
public static void Main()
{
    int []arr = {4, 6, 2, 4, 8, 0, 6, 2};
    int n = arr.Length;
    findSubarrays(arr, n);
}
}
 
// This code is contributed by PrinciRaj1992


Javascript




<script>
// javascript program to break given array into maximum
// number of subarrays with equal average.
 
    function findSubarrays(arr , n) {
        // To store all points where we can break
        // given array into equal average subarrays.
        var result = [];
 
        // Compute total array sum
        var sum = 0;
        for (i = 0; i < n; i++)
            sum += arr[i];
 
        var curr_sum = 0; // Current Sum
        var prev_index = -1; // Index of previous subarray
 
        for (i = 0; i < n; i++) {
            curr_sum += arr[i];
 
            // If current point is a break point. Note that
            // we don't compare actual averages to avoid
            // floating point errors.
            if (sum * (i - prev_index) == curr_sum * n) {
                // Update current sum and previous index
                curr_sum = 0;
                prev_index = i;
 
                // Add current break point
                result.push(i);
            }
        }
 
        // If last break point was not end of array, we
        // cannot break the whole array.
        if (prev_index != n - 1) {
            document.write("Not Possible");
            return;
        }
 
        // Printing the result in required format
        document.write("(0, " + result[0] + ")<br/>");
        for (i = 1; i < result.length; i++)
            document.write("(" + (result[i - 1] + 1) + ", " + result[i] + ")<br/>");
    }
 
    // Main Entry function code
     
        var arr = [ 4, 6, 2, 4, 8, 0, 6, 2 ];
        var n = arr.length;
        findSubarrays(arr, n);
 
// This code contributed by aashish1995
</script>


Output

(0, 0)
(1, 2)
(3, 3)
(4, 5)
(6, 7)

Time complexity: O(n) 
Auxiliary Space: O(1)

 



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