295. Find Median from Data Stream

  • 题目思路

  • 代码实现

  • 1 code1
class MedianFinder
{
public:
    /** initialize your data structure here. */
    MedianFinder()
    {
        maxheapsize = 0;
        minheapsize = 0;
    }

    void addNum(int num)
    {
        //1 和大根堆的堆顶元素进行比较
        //比大根堆的堆顶元素大--->将元素插入的小根堆--->插入过程发现heapsize的差大于1--->小根堆弹出堆顶元素给大根堆,小根堆插入新元素
        //比大根堆的堆顶元素小--->将元素插入到大根堆--->插入过程发现heapsize的差大于1--->大根堆弹出堆顶元素给小根堆,大根堆插入新元素
        if (maxheapsize == 0)
        {
            maxheap.push_back(num);
            make_heap(maxheap.begin(), maxheap.end());
            maxheapsize++;
        }
        else
        {
            if (num > maxheap[0])  //num 比大根堆的堆顶大
            {

                if (minheapsize + 1 - maxheapsize > 1)
                {
                    //先弹出 在插入
                    pop_heap(minheap.begin(), minheap.end(), std::greater<>{});
                    auto smallest = minheap.back();
                    minheap.pop_back();
                    minheapsize--;

                    //最大堆插入
                    maxheap.push_back(smallest);
                    push_heap(maxheap.begin(), maxheap.end());
                    maxheapsize++;

                    //最小堆插入
                    minheap.push_back(num);
                    push_heap(minheap.begin(), minheap.end(), std::greater<>{});
                    minheapsize++;
                }
                else
                {
                    //将元素插入的小根堆
                    minheap.push_back(num);
                    push_heap(minheap.begin(), minheap.end(), std::greater<>{});
                    minheapsize++;
                }
            }
            else  // num <= 大根堆的堆顶
            {
                if (maxheapsize + 1 - minheapsize > 1)
                {
                    //大根堆弹出堆顶元素给小根堆,大根堆插入新元素
                    //先弹出 在插入
                    pop_heap(maxheap.begin(), maxheap.end());
                    auto largest = maxheap.back();
                    maxheap.pop_back();
                    maxheapsize--;

                    //最小堆插入
                    minheap.push_back(largest);
                    push_heap(minheap.begin(), minheap.end(), std::greater<>{});
                    minheapsize++;

                    //最大堆插入
                    maxheap.push_back(num);
                    push_heap(maxheap.begin(), maxheap.end());
                    maxheapsize++;
                }
                else
                {
                    //将元素插入大根堆
                    maxheap.push_back(num);
                    push_heap(maxheap.begin(), maxheap.end());
                    maxheapsize++;
                }
            }
        }


    }  //end void addNum(int num) 

    double findMedian()
    {
        if (maxheapsize == 1 && minheapsize == 0)
        {
            return maxheap[0];
        }
        if ((maxheapsize + minheapsize) % 2 == 0)
        {
            //当前两个堆中的元素共偶数个
            return double(maxheap[0] + minheap[0]) / 2;
        }
        else
        {
            return minheap[0];
        }
    }
private:
    vector<int> maxheap;  //大根堆
    vector<int> minheap;  //小根堆
    int maxheapsize;
    int minheapsize;

};
  • 2 code2
class MedianFinder
{
public:
    /** initialize your data structure here. */
    MedianFinder()
    {
        maxheapsize = 0;
        minheapsize = 0;
    }

    void addNum(int num)
    {   
        if (minheapsize == 0)
        {
            minheap.push_back(num);
            make_heap(minheap.begin(), minheap.end(), std::greater<>{});
            minheapsize++;
        }
        else
        {
            if (num <= minheap[0])  //num <= 小根堆的堆顶
            {
                //应该插入大根堆 下面就插入大根堆的情况进行讨论

                if (maxheapsize + 1 - minheapsize > 1)
                {
                    //大根堆弹出堆顶元素给小根堆,大根堆插入新元素
                    
                    //先弹出 在插入
                    pop_heap(maxheap.begin(), maxheap.end());
                    auto largest = maxheap.back();
                    maxheap.pop_back();
                    maxheapsize--;

                    //最小堆插入
                    minheap.push_back(largest);
                    push_heap(minheap.begin(), minheap.end(), std::greater<>{});
                    minheapsize++;

                    //最大堆插入
                    maxheap.push_back(num);
                    push_heap(maxheap.begin(), maxheap.end());
                    maxheapsize++;

                }
                else
                {
                    //直接插入大根堆
                    maxheap.push_back(num);
                    push_heap(maxheap.begin(), maxheap.end());
                    maxheapsize++;
                }

            }
            else  // num > 小根堆的堆顶
            {
                //应该插入小根堆 下面就插入小根堆的情况进行讨论

                if (minheapsize + 1 - maxheapsize > 1)
                {
                    //先弹出 在插入
                    pop_heap(minheap.begin(), minheap.end(), std::greater<>{});
                    auto smallest = minheap.back();
                    minheap.pop_back();
                    minheapsize--;

                    //最大堆插入
                    maxheap.push_back(smallest);
                    push_heap(maxheap.begin(), maxheap.end());
                    maxheapsize++;

                    //最小堆插入
                    minheap.push_back(num);
                    push_heap(minheap.begin(), minheap.end(), std::greater<>{});
                    minheapsize++;
                }
                else
                {
                    //直接插入小根堆
                    minheap.push_back(num);
                    push_heap(minheap.begin(), minheap.end(), std::greater<>{});
                    minheapsize++;
                }
            }
        }
    }  //end void addNum(int num) 

    double findMedian()
    {
        if (minheapsize == 1 && maxheapsize == 0)
        {
            return minheap[0];
        }

        if ((maxheapsize + minheapsize) % 2 == 0)
        {
            return double(maxheap[0] + minheap[0]) / 2;
        }
        else  //奇数个
        {
            return maxheap[0];
        }
    }
private:
    vector<int> maxheap;  //大根堆
    vector<int> minheap;  //小根堆
    int maxheapsize;
    int minheapsize;

};

code2对于递增序列,如{1,2,3,4,5}输出的值不正确。
code1和code2都是有问题的代码,稍后将正确代码上传。

上一篇:CF Round # 295 (Div. 1)题解


下一篇:牛客入门题单:搜索与搜索剪枝