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;
    
    }
  • 相关阅读:
    360天擎安装上之后,手机开热点之后就没有办法连接
    Redis基本数据类型--Hash(哈希)
    Redis基本数据类型--Set
    redis的五种基本数据类型之List
    Redis的五种基本数据类型 String
    Android应用程序的安装位置
    Java中long和Long有什么区别(转)
    Logcat打印调试信息
    Java GUI图形界面开发工具
    CSDN精选Android开发博客
  • 原文地址:https://www.cnblogs.com/silentteller/p/12119109.html
Copyright © 2011-2022 走看看