Queries to calculate average of an array after removing K smallest and largest elements with updates

• Last Updated : 18 Jun, 2021

Given two positive integers N and K, initialize an empty array arr[] and Q number of queries of the following two types:

The task is to process the given queries and print the results accordingly.

Examples:

Input: N = 3, K = 1, Q = 5, Queries[] = { addInteger(4), addInteger(2), calculateSpecialAverage(), addInteger(10), calculateSpecialAverage() }
Output: -1, 4
Explanation:
Below are the queries performed:
Query 1 is to insert element 4 in the array, arr[] becomes {4}.
Query 2 is to insert the element 2 in the array, arr[] becomes {4, 2}.
Query 3 is to find the average. Since the size of the array is less than N(= 3), print -1.
Query 4 is to insert the element 10 in the array, arr[] becomes {4, 2, 10}.
Query 5 is to find the average. Since the size of the array =3, remove K(= 1) the smallest element i.e., 2 and then remove the largest element i.e., 10. Now the average will be 4/1 = 4.

Input: N = 3, K = 1, Q = 5, Queries[] = { addInteger(4), addInteger(21), calculateSpecialAverage() }
Output: -1

Approach: The given problem can be solved by using the multiset. Follow the steps below to solve the problem:

• Initialize three multisets left, right and mid to store K smallest, K largest, and the remaining (N – 2*K) integers.
• Declare a vector v of size N to store the last N integers.
• Declare an integer variable pos to keep track of the current index and an integer sum to store the sum of values in the mid multiset, which is the desired sum for calculating the average of (N – 2*K) integers.
• Define a function add to insert an integer in left, mid, or right multiset based on its value. To insert integer in the correct multiset follow the following steps:
• Initially, insert the integer in the left multiset.
• If the size of the left multiset exceeds k, delete the largest integer from the left multiset and insert it in the mid multiset.
• If the size of mid multiset exceeds (n – 2*k), delete the largest integer from mid multiset and insert it in the right multiset.
• While removing and adding integers in mid multiset maintain the correct value of sum i.e. if an integer is removed from mid multiset subtract its value from the sum and similarly if an integer is added in the mid multiset, add its value to sum, to keep the value of sum updated.
• Declare a function remove to erase the integers from left, right, or mid multiset.
• If the value of the integer num is less than or equal to the largest integer in the left multiset, then find and erase the integer from the left multiset, otherwise search for it in mid or right multiset, based on its value.
• If after the removal of num, the size of the left multiset decreases, delete the smallest integer from the mid multiset and insert it in the left multiset.
• Similarly, for mid multiset, if the size decreases, delete the smallest integer from the right multiset and insert it in the mid multiset.
• Define a function addInteger to add an integer to the current stream:
• If the number of integers in the current stream(sum of the size of left, mid, right multiset) exceeds n, remove the integer at index pos%n.
• Call the function add to insert the integer in the left, mid, or right multiset, based on its value.
• Define the function calculateSpecialAverage to return the special average:
• If the number of integers in the stream is less than N, then print -1.
• Otherwise, print the average as (sum/(N – 2*K)).

Below is the implementation of the above approach:

C++

Output:

-1
4

Time Complexity: O(log N) for addInteger() and O(1) for calculateSpecialAverage()
Auxiliary Space: O(N)

My Personal Notes arrow_drop_up
Recommended Articles
Page :