数据流中的中位数
    题目链接:https://leetcode-cn.com/problems/shu-ju-liu-zhong-de-zhong-wei-shu-lcof/
    图片.png

    思路:维护一个最大堆和一个最小堆,最大堆总是存储比中位数小的一半数据,最小堆总是存储比中位数大的一半数据,从而实现O(1)返回中位数。需要注意维护一个invariant:两个堆的size要么相等要么差1,因此在插入新数据时:

    • 若此时两个堆size相等,先插入到最小堆,然后将最小堆的栈顶数据pop出来插入到最大堆
    • 若此时两个堆size差1(必然是最大堆比最小堆多1个),则先插入到最大堆,然后将最大堆的栈顶数据pop出来插入到最小堆

    上述过程能够保证两个堆总是存放正确的数据。

    参考代码:

    1. class MedianFinder {
    2. public:
    3. /** initialize your data structure here. */
    4. MedianFinder() {
    5. }
    6. void addNum(int num) {
    7. if (maxHeap.size() == minHeap.size()) {
    8. minHeap.push(num);
    9. maxHeap.push(minHeap.top());
    10. minHeap.pop();
    11. return;
    12. }
    13. maxHeap.push(num);
    14. minHeap.push(maxHeap.top());
    15. maxHeap.pop();
    16. }
    17. double findMedian() {
    18. if (maxHeap.size() == minHeap.size()) {
    19. return (maxHeap.top() + minHeap.top())/2.0;
    20. }
    21. return maxHeap.top();
    22. }
    23. private:
    24. priority_queue<int, vector<int>, less<int>> maxHeap;
    25. priority_queue<int, vector<int>, greater<int>> minHeap;
    26. };