Median Of Running Stream of Numbers – (using Set)

• Last Updated : 14 Jan, 2019

Given that integers are being read from a data stream. Find the median of all the elements read so far starting from the first integer until the last integer. This is also called Median of Running Integers.
The given link already contains solution of this problem using Priority Queue.
However, the following solution uses the same concept but the implementation is by using sets.
In this solution, we will print the smaller median in case of even length instead of taking their average.

Examples:

Input: arr[] = {-10, 14, 11, -5, 7}
Output: -10 -10 11 -5 7

Input: arr[] = {2, -5, 14}
Output: 2 -5 2

Recommended: Please try your approach on {IDE} first, before moving on to the solution.

Approach:

• Create two multisets g in ascending order that will store the upper half and s in descending order to store the lower half of the array arr[].
• Insert the first element in s. And initialize the median with this value.
• For every other element of the array x. Check the sizes of both the sets:
• When size(s) > size(g): If x > median then insert the first element of s into g and remove that element from s, insert x into s. Else insert x into g.
• When size(s) < size(g): If x < median then insert the first element of g into s and remove that element from g, insert x into g. Else insert x into s.
• When size(s) = size(g): If x > median. Insert x into s. Else insert x into g.

Below is the implementation of the above approach:

 // C++ program to find running median for  // a stream of integers using Set #include using namespace std;    // Function to print the running median  // for the array arr[] void printRunningMedian(int arr[], int n) {     // Multiset is used to handle duplicates     // Multiset g for storing upper half      // (ascending order)     // The first element will be the smallest)     multiset g;        // Multiset s for storing lower half      // (descending order). The first element      // will be the largest     multiset > s;        s.insert(arr);        // Initialise median with the first element     int med = arr;     printf("%d ", med);        for (int i = 1; i < n; i++) {            // Only add elements to upper half if          // its size less then the size of the         // lower half (maintain only difference         // of 1)         if (s.size() > g.size()) {             if (arr[i] < med) {                 int temp = *s.begin();                 s.erase(s.begin());                 g.insert(temp);                 s.insert(arr[i]);             }             else                 g.insert(arr[i]);                med = *s.begin() > *g.begin() ?                    *g.begin() : *s.begin();         }            // Only add elements to lower half if          // it's size less then the size of the          // upper half (maintain only difference         // of 1)         else if (s.size() < g.size()) {             if (arr[i] > med) {                 int temp = *g.begin();                 g.erase(g.begin());                 s.insert(temp);                 g.insert(arr[i]);             }             else                 s.insert(arr[i]);                med = *s.begin() > *g.begin() ?                     *g.begin() : *s.begin();         }            // If sizes are same         else {             if (arr[i] > med) {                 g.insert(arr[i]);                 med = *g.begin();             }             else {                 s.insert(arr[i]);                 med = *s.begin();             }         }            printf("%d ", med);     }        printf("\n"); }    // Driver code int main() {     int arr[] = { -10, 14, 11, -5, 7 };     int n = sizeof(arr) / sizeof(arr);     printRunningMedian(arr, n);     return 0; }

Output:

-10 -10 11 -5 7

My Personal Notes arrow_drop_up
Recommended Articles
Page :