1-题目-取中位数
一个数据流中,随时可以取得中位数
import java.util.Arrays;import java.util.Comparator;import java.util.PriorityQueue;public class Code06_MadianQuick {public static class MedianHolder {// 大顶堆private PriorityQueue<Integer> maxHeap = new PriorityQueue<Integer>(new MaxHeapComparator());// 小顶堆private PriorityQueue<Integer> minHeap = new PriorityQueue<Integer>(new MinHeapComparator());// 调整两个堆的数据,使其保持相对平衡状态(两个堆的数据的个数相差小于2)private void modifyTwoHeapsSize() {if (this.maxHeap.size() == this.minHeap.size() + 2) {this.minHeap.add(this.maxHeap.poll());}if (this.minHeap.size() == this.maxHeap.size() + 2) {this.maxHeap.add(this.minHeap.poll());}}// 数据流的值应该放到哪个堆中// 小的值放到大顶堆中// 大的值放到小顶堆中public void addNumber(int num) {if (maxHeap.isEmpty() || num <= maxHeap.peek()) {maxHeap.add(num);} else {minHeap.add(num);}modifyTwoHeapsSize();}// 数据流的数据在都放到堆中后,便通过大顶堆和小顶堆的堆顶来计算中位数public Integer getMedian() {int maxHeapSize = this.maxHeap.size();int minHeapSize = this.minHeap.size();if (maxHeapSize + minHeapSize == 0) {return null;}Integer maxHeapHead = this.maxHeap.peek();Integer minHeapHead = this.minHeap.peek();if (((maxHeapSize + minHeapSize) & 1) == 0) {return (maxHeapHead + minHeapHead) / 2;}return maxHeapSize > minHeapSize ? maxHeapHead : minHeapHead;}}// 大顶堆比较器public static class MaxHeapComparator implements Comparator<Integer> {@Overridepublic int compare(Integer o1, Integer o2) {if (o2 > o1) {return 1;} else {return -1;}}}// 小顶堆比较器public static class MinHeapComparator implements Comparator<Integer> {@Overridepublic int compare(Integer o1, Integer o2) {if (o2 < o1) {return 1;} else {return -1;}}}// 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.addNumber(arr[j]);}if (medianHold.getMedian() != getMedianOfArray(arr)) {err = true;printArray(arr);break;}}System.out.println(err ? "Oops..what a fuck!" : "today is a beautiful day^_^");}}
