• + 1 comment

    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 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
    

    }//Solution