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^_^"); } }