剑指offer41:数据流中的中位数

题目描述

如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。我们使用Insert()方法读取数据流,使用GetMedian()方法获取当前读取数据的中位数
 
 直接排序:
class Solution {
    vector<int> numbers;
public:
    void Insert(int num)
    {
        numbers.push_back(num);
        sort(numbers.begin(),numbers.end());
    }

    double GetMedian()
    { 
        
        int len = numbers.size();
        if(len %2 == 0)
            return (numbers[len/2-1]+numbers[len/2])/2.0;
        else
            return numbers[len/2];
    }

};

使用一个大顶堆和一个小顶堆来完成:

class Solution {
    priority_queue<int,vector<int>,greater<int> > smallCap;
    priority_queue<int,vector<int>,less<int> > bigCap;
public:
    void Insert(int num)
    {
        if(smallCap.size() == 0 && bigCap.size() == 0)
            smallCap.push(num);
        else if(smallCap.size()==bigCap.size()){
            if(num<smallCap.top())
                bigCap.push(num);
            else
                smallCap.push(num);
        }else if(smallCap.size()-bigCap.size() == 1){
            
            if(num<smallCap.top())
                bigCap.push(num);
            else{
                bigCap.push(smallCap.top());
                smallCap.pop();
                smallCap.push(num);
            }
        }else if(smallCap.size()-bigCap.size() == -1){
            if(num<smallCap.top()&&num<bigCap.top()){
                smallCap.push(bigCap.top());
                bigCap.pop();
                bigCap.push(num);
            }
            else{
                smallCap.push(num);
            }
        }else{
            return;
        }
    }

    double GetMedian()
    { 
        if(smallCap.size() == bigCap.size()){
            return (smallCap.top() + bigCap.top())/2.0;
        }else if(smallCap.size()-bigCap.size() == 1){
            return smallCap.top();
        }else{
            return bigCap.top();
        }
    }

};

 使用堆的方式可以达到插入为O(logn),取中位数为O(1)的时间复杂度

java实现的更加简洁的写法:

import java.util.*;
public class Solution {
    
    public Comparator<Integer> cmp = new Comparator<Integer>() {
        public int compare(Integer e1,Integer e2){
            return e2 - e1;
        }
    };
    private PriorityQueue<Integer> minHeap = new PriorityQueue<>();
    private PriorityQueue<Integer> maxHeap = new PriorityQueue<>(cmp);
    int count = 0;
    public void Insert(Integer num) {
        
        if((count & 1) == 0){//偶数个,先插入大顶堆,再弹出大顶堆最大元素放入小顶堆
            maxHeap.offer(num);
            minHeap.offer(maxHeap.poll());
        }else{//奇数个,先插入小顶堆,再弹出小顶堆最小元素放入大顶堆
            minHeap.offer(num);
            maxHeap.offer(minHeap.poll());
        }
        count++;
    }

    public Double GetMedian() {
        if((count & 1) == 1)
            return minHeap.peek().doubleValue();
        else
            return (minHeap.peek()+maxHeap.peek())/2.0;
    }


}
原文地址:https://www.cnblogs.com/ttzz/p/13867568.html