Leecode热题100-295.数据流中的中位数-输入 ["MedianFinder", "addNum", "addNum", "findMedian", "addNum", "findMedian"] [, [1], [2], , [3], ] 输出 [null, null, null, 1.5, null, 2.0] 解释 MedianFinder medianFinder = new MedianFinder; medianFinder.addNum(1); // arr = [1] medianFinder.addNum(2); // arr = [1, 2] medianFinder.findMedian; // 返回 1.5 ((1 + 2) / 2) medianFinder.addNum(3); // arr[1, 2, 3] medianFinder.findMedian; // return 2.0 提示:

时间:2024-10-07 07:32:51
  • -105 <= num <= 105
  • 在调用 findMedian 之前,数据结构中至少有一个元素
  • 最多 5 * 104 次调用 addNum 和 findMedian

本题我用的是双堆的解法,一个小根堆,一个大根堆,堆的特性要了解,默认情况下顶上是小的,越往下越大(小顶堆)

class MedianFinder {
    /**先定义两个堆,一个小根(大顶)堆,用来放小的数,一个大跟堆(小顶)用来放大的数
    记住堆默认是小顶堆(大根堆)*/
    PriorityQueue<Integer> minHeap;
    PriorityQueue<Integer> maxHeap;

    public MedianFinder() {
        /**初始化两个堆 */
        minHeap = new PriorityQueue<>((a,b)->b-a);
        maxHeap = new PriorityQueue<>();
    }
    
    public void addNum(int num) {
        /**如果加入的数比maxHeap的顶(这个堆里最大的数)大,就放入小顶堆
        其他情况放入小顶堆*/
        if(minHeap.isEmpty() || num <= minHeap.peek()) {
            minHeap.offer(num);
            /**为了平衡 */
            if(minHeap.size() > maxHeap.size() + 1) {
                maxHeap.offer(minHeap.poll());
            }
        } else {
            maxHeap.offer(num);
            /**为了平衡 */
            if(maxHeap.size() > minHeap.size() + 1) {
                minHeap.offer(maxHeap.poll());
            }
        }
    }
    
    public double findMedian() {
        /**谁的元素多弹出谁的顶 */
        if(maxHeap.size() > minHeap.size()) {
            return maxHeap.peek();
        } else if(maxHeap.size() < minHeap.size()) {
            return minHeap.peek();
        } else {
            /**如果元素一样,弹出他们俩的顶的平均数 */
            return (double)(maxHeap.peek() + minHeap.peek())/2;
        }
    }
}

/**
 * Your MedianFinder object will be instantiated and called as such:
 * MedianFinder obj = new MedianFinder();
 * obj.addNum(num);
 * double param_2 = obj.findMedian();
 */