NagareMotome median

Package Penalty for Day5; 

Import java.util.Arrays;
 Import java.util.Comparator;
 Import java.util.PriorityQueue; 

/ * 
 * Q: 
 * How to get the median of a data stream? 
 * If the numerical value is read from the odd data stream, then the median value is located in the middle of all values after sorting. 
 * If an even number value is read out from the data stream, then the median is the average of two numbers after all intermediate values of order. 
 * 
 * Ideas: 
 * Use heap, a large root heap, a little heap root. (Thanks to a little too large to store heap root, the root of the heap to store small number) 
 * first number to read large root heap, 
 * the number of the latter, a large contrast root piles top, or less if the top of the stack into a large heap root , 
 * otherwise attempt into a small heap root, root if small heap space, into, whether by contrast small piles of top root, root is greater than the top of the heap into a small pile. Otherwise, into a large root heap. 
 * 
 * If the difference between two stacks> 1; Remove top of the stack, into which a small number. 
 * 
 * / 
Public  class Code04_MedianInDatastream { 
    
    
    public  static  class MedianHolder{
        PriorityQueue<Integer> minHeap;
        PriorityQueue<Integer> maxHeap; 
        public MedianHolder(){
            this.minHeap = new PriorityQueue<>();
            this.maxHeap = new PriorityQueue<>(new MaxHeapComparator());
        }
        public void modify() {
            int count = maxHeap.size() - minHeap.size();
            if (Math.abs(count) >1) {
                if(count >0) {
                    minHeap.add (maxHeap.poll ()); 
                } the else { 
                    maxHeap.add (minHeap.poll ()); 
                } 
            } 
        } 
        // Native !!!!! to consider the full! ! Empty it? 
        
        public  void the Add ( int NUM) {
             IF (maxHeap.isEmpty ()) { 
                maxHeap.add (NUM); 
                return ; 
            } 
            IF (NUM <= maxHeap.peek ()) { // Note that this is smaller than the large root piles top 
                maxHeap .add (NUM); 
            } the else { // No attempts were placed in a small heap root, try! ! ! try! ! ! 
                if(minHeap.isEmpty ()) { 
                    minHeap.add (num); 
                    return ; 
                } 
                If (num> = minHeap.peek ()) { 
                    minHeap.add (num); 
                } Else { 
                    maxHeap.add (num); 
                } 
            } 
            Modify (); 
        } 
        Public Integer getMedian () {
             int maxHeapSize = maxHeap.size ();
            int minHeapSize = minHeap.size ();
            if (maxHeap.isEmpty () && minHeap.isEmpty ()) {
                 return null ; 
            } 
            Integer maxHeapHead =   maxHeap.peek (); 
            Integer minHeadHead = minHeap.peek ();
            if (((+ maxHeapSize minHeapSize) & 1) == 0 ) {
                 return (maxHeapHead minHeadHead +) / 2 ; 
            } 
            Return minHeapSize> maxHeapSize? minHeadHead: maxHeapHead; 
        } 
    } 
    
    
    Public  static  class MaxHeapComparator implements Comparator <Integer> { 

        @Override 
        public  int compare(Integer o1, Integer o2) {
            // TODO Auto-generated method stub
            return o2 -o1;
        }

    
        
    }
    

    // for test
        public static int[] getRandomArray(int maxLen, int maxValue) {
            int[] res = new int[(int) (Math.random() * maxLen) + 1];
            for (int i = 0; i != res.length; i++) {
                res[i] = (int) (Math.random() * maxValue);
            }
            return res;
        }

        // for test, this method is ineffective but absolutely right
        public static int getMedianOfArray(int[] arr) {
            int[] newArr = Arrays.copyOf(arr, arr.length);
            Arrays.sort(newArr);
            int mid = (newArr.length - 1) / 2;
            if ((newArr.length & 1) == 0) {
                return (newArr[mid] + newArr[mid + 1]) / 2;
            } else {
                return newArr[mid];
            }
        }

        public static void printArray(int[] arr) {
            for (int i = 0; i != arr.length; i++) {
                System.out.print(arr[i] + " ");
            }
            System.out.println();
        }

        public static void main(String[] args) {
            boolean err = false;
            int testTimes = 200000;
            for (int i = 0; i != testTimes; i++) {
                int len = 30;
                int maxValue = 1000;
                int[] arr = getRandomArray(len, maxValue);
                MedianHolder medianHold = new MedianHolder();
                for (int j = 0; j != arr.length; j++) {
                    medianHold.add(arr[j]);
                }
                if (medianHold.getMedian() != getMedianOfArray(arr)) {
                    err = true;
                    printArray(arr);
                    System.out.println(medianHold.getMedian());
                    break;
                }
            }
            System.out.println(err ? "Oops..what a fuck!" : "today is a beautiful day^_^");

        }


}

 

Guess you like

Origin www.cnblogs.com/codinghard/p/11489113.html