Skip to content

Instantly share code, notes, and snippets.

@Vedrana
Created September 8, 2012 14:30
Show Gist options
  • Star 11 You must be signed in to star a gist
  • Fork 8 You must be signed in to fork a gist
  • Save Vedrana/3675434 to your computer and use it in GitHub Desktop.
Save Vedrana/3675434 to your computer and use it in GitHub Desktop.
Median of stream of integers
import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.Queue;
// Given a stream of unsorted integers, find the median element in sorted order at any given time.
// http://www.ardendertat.com/2011/11/03/programming-interview-questions-13-median-of-integer-stream/
public class MedianOfIntegerStream {
public Queue<Integer> minHeap;
public Queue<Integer> maxHeap;
public int numOfElements;
public MedianOfIntegerStream() {
minHeap = new PriorityQueue<Integer>();
maxHeap = new PriorityQueue<Integer>(10, new MaxHeapComparator());
numOfElements = 0;
}
public void addNumberToStream(Integer num) {
maxHeap.add(num);
if (numOfElements%2 == 0) {
if (minHeap.isEmpty()) {
numOfElements++;
return;
}
else if (maxHeap.peek() > minHeap.peek()) {
Integer maxHeapRoot = maxHeap.poll();
Integer minHeapRoot = minHeap.poll();
maxHeap.add(minHeapRoot);
minHeap.add(maxHeapRoot);
}
} else {
minHeap.add(maxHeap.poll());
}
numOfElements++;
}
public Double getMedian() {
if (numOfElements%2 != 0)
return new Double(maxHeap.peek());
else
return (maxHeap.peek() + minHeap.peek()) / 2.0;
}
private class MaxHeapComparator implements Comparator<Integer> {
@Override
public int compare(Integer o1, Integer o2) {
return o2 - o1;
}
}
public static void main(String[] args) {
MedianOfIntegerStream streamMedian = new MedianOfIntegerStream();
streamMedian.addNumberToStream(1);
System.out.println(streamMedian.getMedian()); // should be 1
streamMedian.addNumberToStream(5);
streamMedian.addNumberToStream(10);
streamMedian.addNumberToStream(12);
streamMedian.addNumberToStream(2);
System.out.println(streamMedian.getMedian()); // should be 5
streamMedian.addNumberToStream(3);
streamMedian.addNumberToStream(8);
streamMedian.addNumberToStream(9);
System.out.println(streamMedian.getMedian()); // should be 6.5
}
}
@karthikselva
Copy link

At line 15. Can you please explain why you have the number 10 in constructor ?

@Vedrana
Copy link
Author

Vedrana commented Sep 16, 2013

@karthikselva Because if you want to provide a custom comparator for the PriorityQueue, you also need to provide the initial capacity for it, so 10 is just a random number :)
See http://docs.oracle.com/javase/6/docs/api/java/util/PriorityQueue.html#PriorityQueue(int,%20java.util.Comparator).

@achiever01
Copy link

Excellent implementation, thanks!

May you explain why a custom comparator is required? When I run the code after removing the custom comparator, I get incorrect results.

Thanks in advance.

@sreeprasad
Copy link

The custom comparator is for changing the order of the heap. The default order is min. To convert to max heap, custom comparator is used.
http://docs.oracle.com/javase/6/docs/api/java/util/PriorityQueue.html#PriorityQueue(int,%20java.util.Comparator)

@summit87
Copy link

summit87 commented Sep 2, 2014

Thanks@Vedrana

@bobzhang199102
Copy link

Thank you for your excellent code. Could you please tell me if the capacity of max heap will change? Because if the capacity is set to be 10, and the number of numbers are bigger than 10. What will happen?

@jeryini
Copy link

jeryini commented May 8, 2015

@bobzhang199102, from the PriorityQueue JavaDocs

A priority queue is unbounded, but has an internal capacity governing the size of an array used to store the elements on the queue. It is always at least as large as the queue size. As elements are added to a priority queue, its capacity grows automatically. The details of the growth policy are not specified.

I have added a removeNumberFromStream method, that removes the element if it is contained in either max or min heap. Then it checks if it needs to rebalance heap according to number of elements.

@neoeahit
Copy link

With Java 8:
https://docs.oracle.com/javase/8/docs/api/java/util/PriorityQueue.html

It doesn't require a initial size it seems.

@942u3895hjf
Copy link

Hi - is it possible to public this under an ASF 2.0 license?

@mithuns
Copy link

mithuns commented May 3, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment