zoukankan      html  css  js  c++  java
  • 数据流中的中位数

    题目

      如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。

    思路

      使容器左边的数都小于右边的数,即使左右两边的数没有排序,也能根据左边最大的数和右边最小的数来实现查中位数。所以左边用大顶锥实现,右边用小顶锥实现。只需要O(1)的时间就可以实现的到顶锥的数据。

      如果数据总数目是偶数,插入小顶锥,否则插入大顶锥。要保证大顶锥中的数字都小于小顶锥中的数字,如果是偶数时,插入小顶锥,如果此时的数据比小顶锥中的数据小,怎么办?

      解决:

        插入小顶锥时,先把数据插入大顶锥,接着把大顶锥中最大数字拿出来插入小顶锥,最终插入的数字就是原大顶锥中最大的数字,这样就保证了小顶锥中的数字都比大顶锥中的数字大。

        插入大顶锥与插入小顶锥类似...

    #include <iostream>
    #include <algorithm>
    #include <vector>
    using namespace std;
    
    template <typename T>
    class Solution
    {
        public:
            void insert(T &num);
            T get_num();
        private:
            vector<T> min;//右边最小堆--第一个数字最小 
            vector<T> max;//左边最大堆---第一个数字最大 
    };
    template <typename T>
    void Solution<T>::insert(T &num)
    {
        if(((min.size()+max.size())&1)==0)//偶数 
        {
            if(max.size()>0&&num<max[0])
            {
                max.push_back(num);
                push_heap(max.begin(),max.end(),less<T>());//升序 
                
                num=max[0];
                
                pop_heap(max.begin(),max.end(),less<T>());//将第一个元素与最以后一个元素替换 
                max.pop_back();//弹出最后一个元素 
            }
            min.push_back(num);
            push_heap(min.begin(),min.end(),greater<T>());//降序 
        }
        else
        {
            if(min.size()>0&&min[0]<num)
            {
                min.push_back(num);
                push_heap(min.begin(),min.end(),greater<T>());
                
                num=min[0];
                
                pop_heap(min.begin(),min.end(),greater<T>());
                min.pop_back();
            }
            max.push_back(num);
            push_heap(max.begin(),max.end(),less<T>());
        }    
    }
    template<typename T>
    T Solution<T>::get_num()
    {
        int size=max.size()+min.size();
        if(!size)
        {
            cerr<<"no number available"<<endl;
            return 0x3f3f;
        }
        int mid=0;
        if(size&1)
            return min[0];
        else
            return (min[0]+max[0])/2;
    }
    int main()
    {
        vector<int> v{1,4,9,7,5,6};
        Solution<int> s;
        for(int i=0;i<v.size();++i)
        {
            s.insert(v[i]);
        }
        if(s.get_num()!=0x3f3f)
            cout<<s.get_num()<<endl;
        else
        {
            cerr<<"数组有误."<<endl;
            return 0;
        }
        return 0;
    }

     code

    class Solution {
    public:
        void Insert(int num)
        {
            if(max.empty()||num<=max.top())
                max.push(num);
            else
                min.push(num);
            //左边的大顶锥最多比右边的小顶锥的容量大一(奇数)
            if(max.size()==min.size()+2)
            {
                min.push(max.top());
                max.pop();
            }
            //最后返回的是左边的大顶锥锥顶,所以右边的小顶锥不能比左边的大顶锥容量大
            if(max.size()+1==min.size())
            {
                max.push(min.top());
                min.pop();
            }
            return ;
        }
    
        double GetMedian()
        { 
            return max.size()==min.size()?(max.top()+min.top())/2.0:max.top();
        }
    private:
        priority_queue<int,vector<int>,less<int>> max;
        priority_queue<int,vector<int>,greater<int>> min;
    };
  • 相关阅读:
    hdoj 2544 最短路径
    树状数组 hdoj1166
    并查集学习
    1402大数相乘 FFT算法学习!
    hdu1014
    动态规划 简单题dp
    迷宫路径
    简单的动态规划dp
    poj 3282 (bFS)
    背包问题,看不懂,啊!!!!!!!!dp
  • 原文地址:https://www.cnblogs.com/tianzeng/p/10236559.html
Copyright © 2011-2022 走看看