Average of max K numbers in a stream in C++


The average of number in a stream means calculating the average after every insertion. But in this problem, we need to find the average of max K numbers in a stream i.e. only k numbers of the array are considered for calculating the average. When we add a number if it is greater than any of the numbers that contribute to the average then only it is considered otherwise the average remains the same.

Let’s take an example to understand the concept better −

Input : n = 4 , k = 3 , array = { 4, 9, 1 , 5} , stream = {2, 6, 3 , 7 }
Output : 6 , 6.66 , 6.66 , 7.33

In the first insertion the average is 4 + 9 + 5 / 3 = 6 , 2 inserted no change.

In the second insertion, the average is 6 + 9 + 5 / 3 = 6.66, since 6 is added to the array which is greater than 4 which is considered in calculating the average so it is replaced by 6 making the average 6.66.

In the third insertion the average is 6 + 9 + 5 / 3 = 6.66 , 3 inserted no change.

In the forth insertion the average is 6 + 9 + 7 / 3 = 7.33, 7 inserted which replaced 5 making the average 7.33.

Now, since we know about the problem of an average of k max numbers of a stream. Let’s derive a solution for this problem. For problems like this, where insertion or deletion of elements is performed we use heap for finding the solution.

Algorithm

Step 1 : create a min heap of K Max elements of the array. ( the smallest of the K elements is at the root).
Step 2 : for every element of the stream. Do :
Step 3 : Compare the element with the root of the heap.
Step 4 : If root is less than element then replace the root with new element.

Example

 Live Demo

import java.util.*;
public class Kmaxsum {
   static void max_average_k_numbers(int n, int k, int m, int[] arr, int[] query){
      double max_avg = 0.0;
      PriorityQueue<Integer> pq = new PriorityQueue<Integer>();
      Arrays.sort(arr);
      double sum = 0;
      for (int i = n - 1; i >= n - k; i--) {
         pq.add(arr[i]);
         sum = sum + arr[i];
      }
      for (int i = 0; i < m; i++) {
         if (query[i] > pq.peek()) {
            int polled = pq.poll();
            pq.add(query[i]);
            sum = sum - polled;
            sum = sum + query[i];
         }
         max_avg = sum / (double)k;
         System.out.println(max_avg);
      }
   }
   public static void main(String[] args){
      int n = 4;
      int k = 3;
      int m = 4;
      int[] arr = new int[] { 4, 9, 1 , 5 };
      int[] query = new int[] { 2, 6, 3 , 7 };
      System.out.println("The sum of K max sums of stream is : ");
      max_average_k_numbers(n, k, m, arr, query);
   }
}

Output

The sum of K max sums of stream is :
6.0
6.666666666666667
6.666666666666667
7.333333333333333

Updated on: 24-Oct-2019

117 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements