We use cookies to ensure you have the best browsing experience on our website. Please read our cookie policy for more information about how we use cookies.
/*
We want any one of the two conditions-
1) maxHeap.size() == minHeap.size()
2) maxHeap.size() = minHeap.size()+1
to always be true
Two priority queues are used:
Max heap stores the smaller half of elements(in terms of value) IN REVERSE ORDER, and,
Reversed because it has to peek/poll the highest of the smaller half, which is potentially a median
Min heap stores the bigger half of elements (in terms of value)
*/
public class Solution {
private static PriorityQueue<Long> minHeap = new PriorityQueue<>();
// keeps track of the LARGE numbers
private static PriorityQueue<Long> maxHeap = new PriorityQueue<>(Collections.reverseOrder());
// keeps track of the SMALL numbers
private static HashMap hm=new HashMap();
//to keep a count, and alert when the emelent to be deleted is not found
public static void main(String[] args) {
//----------------input-------------------------
Scanner in = new Scanner(System.in);
int n = in.nextInt();
for(int i=0; i < n; i++) {
medianTracker(in);//pass Scanner as the argument
}
}//main
public static void medianTracker(Scanner in) {
/* This function is invoked n times from main(), which in turn invokes the add or delete function, and displays the median.*/
String op=in.next();
long num=in.nextInt();
if(op.equals("a")) {
addNumber(num,hm);//add the element to the appripriate priority queue
getMedian();//display the median
}//if ax
else if(op.equals("r")) {
//Returns false for any of the two conditions:element to be deleted does not exist or after deletion, priority queues become empty
boolean check=delNumber(num,hm);//delete the element if exists
if(check==true)
{//if the number exists
getMedian();//display the median
}
else System.out.println("Wrong!");//else print wrong
}//if rx
private static void addNumber(long num, HashMap hm) {
/*The basic underlying condition is that if the num is greater than the largest number of maxheap, it is added to the min heap, else it is added to the maxheap. Then adjustments are made so that (maxheap.size-minheap.size) is 0 or 1 */
if (maxHeap.isEmpty()) {
maxHeap.add(num);
}
else if (maxHeap.size() == minHeap.size()) {
//if both heaps are currently equal
if (num > maxHeap.peek()) {//and element is larger than median
minHeap.add(num);//add to minHeap
maxHeap.add(minHeap.remove());//adjustment
}
else {
maxHeap.add(num);//else add to maxheap
}
}//else if
else if (maxHeap.size() > minHeap.size())
{//if maxheap size is 1 greater than that of min heap
if (num > maxHeap.peek()) {//element greater than median
minHeap.add(num);//add to min heap
}
else {
maxHeap.add(num);//else add to max heap
minHeap.add(maxHeap.remove());//adjustment
}
}//else if
if(hm.containsKey(num)){hm.put(num,((Long)hm.get(num)+1));}
else{ hm.put(num,(long)1);} //mark the existence
}
//----------------------------------------
private static boolean delNumber(long num,HashMap hm) {
/*The basic underlying condition is that if the num is greater than the largest number of maxheap, it is deleted from the min heap, else it is deleted from the maxheap. Then adjustments are made so that (maxheap.size-minheap.size) is 0 or 1 */
//-----handle the non existent element condition---------------------------------
if((!hm.containsKey(num) )|| ((long)hm.get(num)<=0)) {return false;}//element does not exist or has been deleted
//--------------------------------------------------------------------------------
else {
//if element exists, decrease its count by 1
long value=(Long)(hm.get(num))-1;
hm.put(num,value);
if (maxHeap.size() > minHeap.size() ){
if (num <= maxHeap.peek()){
maxHeap.remove(num);
if(maxHeap.size()==0){return false;}//if maxheap becomes empty after deletion
}//if
else {
//belonged to greater half that is- min heap
minHeap.remove(num);
minHeap.add(maxHeap.remove());
}//else
}// if
else if (maxHeap.size() == minHeap.size()) {
//if both heaps are currently equal
if (num > maxHeap.peek()) {
//the number was in the min heap(greater half)
minHeap.remove(num);
}
else {
//the number was in the max heap(smaller half)
maxHeap.remove(num);
maxHeap.add(minHeap.remove());
}
}//else if
return true;
}//else
}//delNumber
//------------------------------------------
private static void getMedian() { // problem statement said: will always have at least 1 element
double res; if (maxHeap.size() > minHeap.size()) {
res=maxHeap.peek();
}
else
{
res=(maxHeap.peek() + minHeap.peek()) / 2.0;
}
if((double)(res - (long) res)==0.0){ //if whole number
System.out.printf("%.0f\n", res);
}
else{//if fractional, display till one decimal point
System.out.printf("%.1f\n", res);
}
}//getMedian
Median Updates
You are viewing a single comment's thread. Return to all comments →
My Java Solution using Priority Queue:
import java.io.; import java.util.; import java.text.; import java.math.; import java.util.regex.*; import java.util.Scanner; import java.util.PriorityQueue;
/* We want any one of the two conditions- 1) maxHeap.size() == minHeap.size() 2) maxHeap.size() = minHeap.size()+1 to always be true
Two priority queues are used: Max heap stores the smaller half of elements(in terms of value) IN REVERSE ORDER, and, Reversed because it has to peek/poll the highest of the smaller half, which is potentially a median Min heap stores the bigger half of elements (in terms of value) */
public class Solution {
private static HashMap hm=new HashMap(); //to keep a count, and alert when the emelent to be deleted is not found
//----------------------------------------------------------------------
//Returns false for any of the two conditions:element to be deleted does not exist or after deletion, priority queues become empty boolean check=delNumber(num,hm);//delete the element if exists if(check==true)
{//if the number exists getMedian();//display the median } else System.out.println("Wrong!");//else print wrong }//if rx
//----------------------------------------------------------
//----------------------------------------
//------------------------------------------
}//Solution