zoukankan      html  css  js  c++  java
  • 剑指Offer-63.数据流中的中位数(C++/Java)

    题目:

    如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。我们使用Insert()方法读取数据流,使用GetMedian()方法获取当前读取数据的中位数。

    分析:

    我们可以想象出一个排序数组的中位数可以将数组分成两部分,那么我们利用最大堆和最小堆来分别存储这两部分,且如果要求中位数时,可以通过直接返回堆顶元素,在O(1)的时间内求解。

    要保证最大堆的所有元素小于等于最小堆的元素,在插入元素的时候通过已插入数字数目来判断:

    如果插入数目是偶数,就将元素插入最大堆,然后再将最大堆中堆顶元素取出,插入最小堆中。

    如果插入数目是奇数,就将元素插入最小堆,然后再将最小堆中堆顶元素取出,插入最大堆中。

    这样做就可以保证最大堆的所有元素小于等于最小堆的元素。

    然后如果数目是奇数时,中位数等于最小堆的堆顶元素,为偶数时,中位数等于最小堆和最大堆的堆顶元素的平均值。

    以[5,2,3,4,1,6,7,0,8]为例:

    插入元素 最小堆 最大堆 中位数
    5 [5] [] 5
    2 [5] [2] 3.5
    3 [3,5] [2] 3
    4 [4,5] [3,2] 3.5
    1 [3,4,5] [2,1] 3
    6 [4,5,6] [3,2,1] 3.5
    7 [4,5,6,7] [3,2,1] 4
    0 [4,5,6,7] [3,2,1,0] 3.5
    8 [4,5,6,7,8] [3,2,1,0] 4

    程序:

    C++

    class Solution {
    public:
        void Insert(int num)
        {
            if(c % 2 == 0){
                maxHeap.push(num);
                minHeap.push(maxHeap.top());
                maxHeap.pop();
            }
            else{
                minHeap.push(num);
                maxHeap.push(minHeap.top());
                minHeap.pop();
            }
            c++;
        }
    
        double GetMedian()
        { 
            if(c % 2 == 0){
                return (double)(maxHeap.top() + minHeap.top()) / 2;
            }
            else{
                return (double)minHeap.top();
            }
        }
    private:
        priority_queue<int, vector<int>, less<int> > maxHeap;
        priority_queue<int, vector<int>, greater<int> > minHeap;
        int c = 0;
    };

    Java

    import java.util.PriorityQueue;
    import java.util.Comparator;
    public class Solution {
    
        public void Insert(Integer num) {
            if(count % 2 == 0){
                maxHeap.offer(num);
                minHeap.offer(maxHeap.poll());
            }else{
                minHeap.offer(num);
                maxHeap.offer(minHeap.poll());
            }
            count++;
        }
    
        public Double GetMedian() {
            if(count % 2 == 0){
                return new Double(minHeap.peek() + maxHeap.peek()) / 2;
            }else{
                return new Double(minHeap.peek());
            }
        }
        private PriorityQueue<Integer> minHeap = new PriorityQueue<Integer>();
        private PriorityQueue<Integer> maxHeap = new PriorityQueue<Integer>(11, new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2 - o1;
            }
        });
        private int count = 0;
    
    }
  • 相关阅读:
    TensorFlow学习('utf-8' codec can't decode byte 0xff in position 0: invalid start byte)
    Python常用库之三:Matplotlib
    线性回归 Python实现
    go 算法 查询字符在字符串中的位置
    Python与Go快速排序
    Python与Go斐波那契数列
    Python与Go选择排序
    Python与Go插入排序
    Python与Go冒泡排序
    git clone直接提交用户名和密码
  • 原文地址:https://www.cnblogs.com/silentteller/p/12119109.html
Copyright © 2011-2022 走看看