81.数据流中位数

来源:互联网 发布:致胜轮毂数据 编辑:程序博客网 时间:2024/06/06 17:31

数字是不断进入数组的,在每次添加一个新的数进入数组的同时返回当前新数组的中位数。

  • 中位数是排序后数组的中间值,如果有数组中有n个数,则中位数为A[(n-1)/2]。
  • 比如:数组A=[1,2,3]的中位数是2,数组A=[1,19]的中位数是1。

样例

持续进入数组的数的列表为:[1, 2, 3, 4, 5],则返回[1, 1, 2, 2, 3]

持续进入数组的数的列表为:[4, 5, 1, 3, 2, 6, 0],则返回 [4, 4, 4, 3, 3, 3, 3]

持续进入数组的数的列表为:[2, 20, 100],则返回[2, 2, 20]

挑战 

时间复杂度为O(nlogn)


第一次用的插入排序,花了948ms。

后来改进为两个堆,一个最大堆储存前一半数,一个最小堆储存后一半数,插入次数是奇数时将值插入最大堆,是偶数时插入最小堆,同时保证最大堆的最大值小于最小堆的最小值。用时59ms。确实快了不少。顺便写了写堆的插入删除操作(堆下标从0开始)。

#include<iostream>#include<vector>using namespace std;void insertmaxheap(vector<int> &maxheap, int tar)    {        int pos = maxheap.size();        maxheap.push_back(tar);        if(pos == 0)            return;                 int child = pos;        int par = (pos-1)/2;        while(tar > maxheap[par] )        {            maxheap[child] = maxheap[par];            child = par;            if(par == 0)                break;            else                par = (par-1)/2;        }        maxheap[child] = tar;    }    int deletemaxheap(vector<int> &maxheap)    {        int ret = maxheap[0];        int pos = maxheap.size()-1;//新的size        int tar = maxheap[pos];        maxheap.pop_back();                if(pos == 0)            return ret;        else if(pos == 1)        {            maxheap[0] = tar;            return ret;        }        else if(pos == 2)        {            if(tar>maxheap[1])            {                maxheap[0] = tar;            }            else            {                maxheap[0] = maxheap[1];                maxheap[1] = tar;            }            return ret;        }                int par = 0;        int child = maxheap[1] < maxheap[2] ? 2 : 1;        while(tar < maxheap[child])        {            maxheap[par] = maxheap[child];            par = child;            if(2*child+1 < pos && 2*child+2>=pos)                child = 2*child+1;            else if(2*child+1 >= pos && 2*child+2>=pos)                break;            else                child = maxheap[2*child+1] < maxheap[2*child+2] ? 2*child+2 : 2*child+1;        }        maxheap[par] = tar;                return ret;    }    void insertminheap(vector<int> &minheap, int tar)    {        int pos = minheap.size();        minheap.push_back(tar);        if(pos == 0)            return;        int child = pos;        int par = (pos-1)/2;        while(tar < minheap[par] )        {            minheap[child] = minheap[par];            child = par;            if(par == 0)                break;            else                par = (par-1)/2;        }        minheap[child] = tar;    }    int deleteminheap(vector<int> &minheap)    {        int ret = minheap[0];        int pos = minheap.size()-1;//新的size        int tar = minheap[pos];        minheap.pop_back();                if(pos == 0)            return ret;        else if(pos == 1)        {            minheap[0] = tar;            return ret;        }        else if(pos == 2)        {            if(tar < minheap[1])            {                minheap[0] = tar;            }            else            {                minheap[0] = minheap[1];                minheap[1] = tar;            }            return ret;        }                int par = 0;        int child = minheap[1] > minheap[2] ? 2 : 1;        while(tar > minheap[child])        {            minheap[par] = minheap[child];            par = child;            if(2*child+1 < pos && 2*child+2>=pos)                child = 2*child+1;            else if(2*child+1 >= pos && 2*child+2>=pos)                break;            else                child = minheap[2*child+1] > minheap[2*child+2] ? 2*child+2 : 2*child+1;        }        minheap[par] = tar;                return ret;    }vector<int> medianII(vector<int> &nums) {        // write your code here        int m = nums.size();        if(m==0) return vector<int>(0);        /*        vector<int> vec(m, nums[0]);        //948ms        int i=0, j=0;        for(i=1; i<m; i++)        {            int temp = nums[i];            for(j=i; j>0 && temp<nums[j-1]; j--)            {                nums[j] = nums[j-1];            }            nums[j] = temp;            vec[i] = nums[i/2];        }        return vec;        */        vector<int> maxheap;        vector<int> minheap;        vector<int> ret(m, 0);        for(int i=0; i<m; i++)        {                        if(!(i&1))//ji ci            {                insertminheap(minheap, nums[i]);                int min = deleteminheap(minheap);                insertmaxheap(maxheap, min);            }            else// ou ci            {                insertmaxheap(maxheap, nums[i]);                int max = deletemaxheap(maxheap);                insertminheap(minheap, max);            }            ret[i] = maxheap[0];        }        return ret;    }    int main(){vector<int> vec = {1,2,3,4,5};vector<int> ret(medianII(vec));for(auto x:ret)cout<<x<<" ";cout<<endl;}

0 0
原创粉丝点击