Average of max K numbers in a stream
Last Updated :
22 Mar, 2023
Given a list of N numbers, and an integer ‘K’. The task is to print the average of max ‘K’ numbers after each query where a query consists of an integer element that needs to be added to the list of elements.
Note: The queries are defined with an integer array ‘q’
Examples:
Input: N = 4, K = 3, arr = {1, 2, 3, 4}, q = {7, 2, 1, 5}
Output: 4.666666 4.666666 4.666666 5.333333
After query 1, arr = {1, 2, 3, 4, 7} and
the average of max K (i.e. {3, 4, 7}) elements is 4.666666.
After query 2, arr = {1, 2, 3, 4, 7, 2} and
the average is 4.666666 for {3, 4, 7}.
After query 3, arr = {1, 2, 3, 4, 7, 2, 1} and
the average is 4.666666 for {3, 4, 7}.
After query 4, arr = {1, 2, 3, 4, 7, 2, 5} and
the average is 5.333333 for {4, 5, 7}.
Input: N = 5, K = 4, arr = {1, 2, 2, 3, 3}, q = {2, 5, 1}
Output: 2.5 3.25 3.25
Approach:
Heap (Min Heap) data structure can be used to solve problems like these where insertion and deletions of the elements can be performed in O(log n) time.
- Initially, store the max k elements from the given list of elements in the min heap.
- If the incoming element is less than or equal to the element currently at the root of the min heap then discard the element as it’ll have no effect on the average.
- Else if, if the number is greater than the root element then remove the root of the min heap followed by insertion of the new element, and then calculate the average of the elements currently in the heap.
- Print the average and repeat the above two steps for all incoming elements.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
void max_average_k_numbers( int n, int k, int m, int arr[],
int query[])
{
double max_avg = 0.0;
priority_queue< int , vector< int >, greater< int > > pq;
sort(arr, arr + n);
double sum = 0;
for ( int i = n - 1; i >= n - k; i--) {
pq.push(arr[i]);
sum = sum + arr[i];
}
for ( int i = 0; i < m; i++) {
if (query[i] > pq.top()) {
int polled = pq.top();
pq.pop();
pq.push(query[i]);
sum = sum - polled;
sum = sum + query[i];
}
max_avg = sum / ( double )k;
cout << max_avg << endl;
}
}
int main()
{
int n = 4;
int k = 3;
int m = 4;
int arr[] = { 1, 2, 3, 4 };
int query[] = { 7, 2, 1, 5 };
max_average_k_numbers(n, k, m, arr, query);
return 0;
}
|
Java
import java.util.*;
class GFG {
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 [] { 1 , 2 , 3 , 4 };
int [] query = new int [] { 7 , 2 , 1 , 5 };
max_average_k_numbers(n, k, m, arr, query);
}
}
|
Python3
import heapq
def max_average_k_numbers(n, k, m, arr, query):
max_avg = 0.0
pq = []
Sum = 0
arr.sort()
for i in range (n - 1 , n - k - 1 , - 1 ):
pq.append(arr[i])
Sum + = arr[i]
heapq.heapify(pq)
for i in range (m):
if query[i] > pq[ 0 ]:
polled = pq[ 0 ]
pq[ 0 ] = pq[ - 1 ]
pq.pop()
pq.append(query[i])
Sum - = polled
Sum + = query[i]
heapq.heapify(pq)
max_avg = Sum / float (k)
print (max_avg)
if __name__ = = '__main__' :
n = 4
k = 3
m = 4
arr = [ 1 , 2 , 3 , 4 ]
query = [ 7 , 2 , 1 , 5 ]
max_average_k_numbers(n, k, m, arr, query)
|
C#
using System;
using System.Collections.Generic;
using System.Linq;
public class MaxAverageKNumbers
{
public static void Calculate( int n, int k, int m, int [] arr, int [] query)
{
double maxAvg = 0.0;
var pq = new SortedSet< int >();
Array.Sort(arr);
double sum = 0;
for ( int i = n - 1; i >= n - k; i--)
{
pq.Add(arr[i]);
sum += arr[i];
}
for ( int i = 0; i < m; i++)
{
if (query[i] > pq.Min)
{
int polled = pq.Min;
pq.Remove(polled);
pq.Add(query[i]);
sum -= polled;
sum += query[i];
}
maxAvg = sum / ( double )k;
Console.WriteLine(maxAvg);
}
}
public static void Main()
{
int n = 4;
int k = 3;
int m = 4;
int [] arr = { 1, 2, 3, 4 };
int [] query = { 7, 2, 1, 5 };
MaxAverageKNumbers.Calculate(n, k, m, arr, query);
}
}
|
Javascript
function max_average_k_numbers(n, k, m, arr, query) {
let max_avg = 0.0;
const pq = new PriorityQueue();
arr.sort((a, b) => a - b);
let sum = 0;
for (let i = n - 1; i >= n - k; i--) {
pq.push(arr[i]);
sum += arr[i];
}
for (let i = 0; i < m; i++) {
if (query[i] > pq.top()) {
const polled = pq.top();
pq.pop();
pq.push(query[i]);
sum -= polled;
sum += query[i];
}
max_avg = sum / k;
console.log(max_avg);
}
}
class PriorityQueue {
constructor() {
this .heap = [];
}
push(val) {
this .heap.push(val);
this .bubbleUp( this .heap.length - 1);
}
pop() {
const last = this .heap.pop();
const popped = this .heap[0];
if ( this .heap.length > 0) {
this .heap[0] = last;
this .bubbleDown(0);
}
return popped;
}
top() {
return this .heap[0];
}
bubbleUp(idx) {
const parent = Math.floor((idx - 1) / 2);
if (parent >= 0 && this .heap[idx] < this .heap[parent]) {
[ this .heap[idx], this .heap[parent]] = [ this .heap[parent], this .heap[idx]];
this .bubbleUp(parent);
}
}
bubbleDown(idx) {
const left = 2 * idx + 1;
const right = 2 * idx + 2;
let smallest = idx;
if (left < this .heap.length && this .heap[left] < this .heap[smallest]) {
smallest = left;
}
if (right < this .heap.length && this .heap[right] < this .heap[smallest]) {
smallest = right;
}
if (smallest !== idx) {
[ this .heap[idx], this .heap[smallest]] = [ this .heap[smallest], this .heap[idx]];
this .bubbleDown(smallest);
}
}
}
const n = 4;
const k = 3;
const m = 4;
const arr = [1, 2, 3, 4];
const query = [7, 2, 1, 5];
max_average_k_numbers(n, k, m, arr, query);
|
Output
4.666666666666667
4.666666666666667
4.666666666666667
5.333333333333333
Complexity Analysis:
- Time Complexity: O(N(log(N))).
- Auxiliary Space: O(N) // N is the length of the array.
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...