Median Of Running Stream of Numbers – (using Set)
Last Updated :
30 Mar, 2023
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
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.Median = top/begin of set with larger size.
- 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. Median = top/begin of set with larger size.
- When size(s) = size(g): If x > median. Insert x into s, Median = begin of g. Else insert x into g.
Below is the implementation of the above approach:
CPP
#include <bits/stdc++.h>
using namespace std;
void printRunningMedian( int arr[], int n)
{
multiset< int > g;
multiset< int , greater< int > > s;
s.insert(arr[0]);
int med = arr[0];
printf ( "%d " , med);
for ( int i = 1; i < n; i++) {
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();
}
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();
}
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" );
}
int main()
{
int arr[] = { -10, 14, 11, -5, 7 };
int n = sizeof (arr) / sizeof (arr[0]);
printRunningMedian(arr, n);
return 0;
}
|
Python3
def printRunningMedian(arr):
g = set ()
s = set ()
s.add(arr[ 0 ])
med = arr[ 0 ]
print (med, end = " " )
for i in range ( 1 , len (arr)):
if len (s) > len (g):
if arr[i] < med:
temp = max (s)
s.remove(temp)
g.add(temp)
s.add(arr[i])
else :
g.add(arr[i])
med = min (g) if max (s) > min (g) else max (s)
elif len (s) < len (g):
if arr[i] > med:
temp = min (g)
g.remove(temp)
s.add(temp)
g.add(arr[i])
else :
s.add(arr[i])
med = min (g) if max (s) > min (g) else max (s)
else :
if arr[i] > med:
g.add(arr[i])
med = min (g)
else :
s.add(arr[i])
med = max (s)
print (med, end = " " )
arr = [ - 10 , 14 , 11 , - 5 , 7 ]
printRunningMedian(arr)
|
Java
import java.util.TreeSet;
public class Solution {
public static void printRunningMedian( int [] arr, int n) {
TreeSet<Integer> g = new TreeSet<Integer>();
TreeSet<Integer> s = new TreeSet<Integer>((a, b) -> (b - a));
s.add(arr[ 0 ]);
int med = arr[ 0 ];
System.out.print(med + " " );
for ( int i = 1 ; i < n; i++) {
if (s.size() > g.size()) {
if (arr[i] < med) {
int temp = s.first();
s.remove(s.first());
g.add(temp);
s.add(arr[i]);
} else {
g.add(arr[i]);
}
med = s.first() > g.first() ? g.first() : s.first();
}
else if (s.size() < g.size()) {
if (arr[i] > med) {
int temp = g.first();
g.remove(g.first());
s.add(temp);
g.add(arr[i]);
} else {
s.add(arr[i]);
}
med = s.first() > g.first() ? g.first() : s.first();
}
else {
if (arr[i] > med) {
g.add(arr[i]);
med = g.first();
} else {
s.add(arr[i]);
med = s.first();
}
}
System.out.print(med + " " );
}
System.out.println();
}
public static void main(String[] args) {
int [] arr = { - 10 , 14 , 11 , - 5 , 7 };
int n = arr.length;
printRunningMedian(arr, n);
}
}
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static void PrintRunningMedian( int [] arr, int n)
{
SortedSet< int > g = new SortedSet< int >();
SortedSet< int > s = new SortedSet< int >(Comparer< int >.Create((a, b) => b.CompareTo(a)));
s.Add(arr[0]);
int med = arr[0];
Console.Write(med + " " );
for ( int i = 1; i < n; i++)
{
if (s.Count > g.Count)
{
if (arr[i] < med)
{
int temp = s.Min;
s.Remove(temp);
g.Add(temp);
s.Add(arr[i]);
}
else
{
g.Add(arr[i]);
}
med = s.Min > g.Min ? g.Min : s.Min;
}
else if (s.Count < g.Count)
{
if (arr[i] > med)
{
int temp = g.Min;
g.Remove(temp);
s.Add(temp);
g.Add(arr[i]);
}
else
{
s.Add(arr[i]);
}
med = s.Min > g.Min ? g.Min : s.Min;
}
else
{
if (arr[i] > med)
{
g.Add(arr[i]);
med = g.Min;
}
else
{
s.Add(arr[i]);
med = s.Min;
}
}
Console.Write(med + " " );
}
Console.WriteLine();
}
static void Main( string [] args)
{
int [] arr = { -10, 14, 11, -5, 7 };
int n = arr.Length;
PrintRunningMedian(arr, n);
}
}
|
Javascript
function printRunningMedian(arr)
{
let g = new Set();
let s = new Set();
s.add(arr[0]);
let med = arr[0];
process.stdout.write(med + " " );
for (let i = 1; i < arr.length; i++)
{
if (s.size > g.size) {
if (arr[i] < med) {
let temp = Math.max(...s);
s. delete (temp);
g.add(temp);
s.add(arr[i]);
} else {
g.add(arr[i]);
}
med = Math.max(...s) > Math.min(...g) ? Math.min(...g) : Math.max(...s);
}
else if (s.size < g.size) {
if (arr[i] > med) {
let temp = Math.min(...g);
g. delete (temp);
s.add(temp);
g.add(arr[i]);
} else {
s.add(arr[i]);
}
med = Math.max(...s) > Math.min(...g) ? Math.min(...g) : Math.max(...s);
}
else {
if (arr[i] > med) {
g.add(arr[i]);
med = Math.min(...g);
} else {
s.add(arr[i]);
med = Math.max(...s);
}
}
process.stdout.write(med + " " );
}
}
let arr = [-10, 14, 11, -5, 7];
printRunningMedian(arr);
|
Share your thoughts in the comments
Please Login to comment...