大小堆运用巧解数据流的中位数

​​​​​​​​​​在这里插入图片描述

一、思路

我们将所有数据平分成两份,前面那一部分用小堆来存,后面的部分用大堆来存,这样我们就能立刻拿到中间位置的值。
在这里插入图片描述

如果是奇数个数字,那么我们就将把中间值放在前面的大堆里,所以会有两种情况,我们将大堆成为left,小堆成为right。

  • 当数据量是偶数的时候,left.size() == right.size(),这时候中间值就是left.top()
  • 当数据量是奇数的时候,这时候的left.size() == right.size() + 1,这时候的中位数就是 (left.size() + right.size()) / 2.0

二、如何存储数据?

因为左边是大堆,右边是小堆,这时候会有两个大类的情况

第一种 left.size() = right.size()

这时候,由于左边的数据都是会比left.top()小,右边的数据都会比左边的数据大,所以我们可以根据这个条件开进行讨论
假如要插入的数据是num

  • 如果left.empty() || num <= left.top() ,这时候就直接将num插进左边的大堆中
  • 如果num > left.top(),这时候应该要插进右边的小堆,但由于我们规定只能两边数据相等,或者右边的比左边的数据量多一个,所以这时候我们要:
    1.先把数据插入进right,
    2.然后拿到right.top(),因为这是right的最小值
    3.将right.top() 插进 left.top()中,然后再让right.pop()

第二种 left.size() > right.size()

  • 如果num > left.top() ,直接把num插进right中
  • 如果num <= left.top(), 这时候由于left的大小比right多1,所以我们可以参考第一种情况那样
  1. 把数据插进left
  2. 将left.top() 插入到 right中
  3. left.pop()

三、代码

class MedianFinder {
public:
    priority_queue<int> left;
    priority_queue<int, vector<int>, greater<int>> right;
    MedianFinder() {

    }
    
    void addNum(int num) {
        if(left.size() == right.size())
        {
            if(left.empty() || left.top() >= num) 
            {
            	left.push(num);
            }
            else if(left.top() < num)   
            {
                right.push(num);
                int y = right.top();
                right.pop();
                left.push(y);
            }
        }
        else
        {
            if(left.top() >= num)   
            {
                left.push(num);
                right.push(left.top());
                left.pop();
            }
            else 
            {
                right.push(num);
            }
        }
        
    }
    
    double findMedian() {
        if(left.size() == right.size()) return (left.top() + right.top()) / 2.0;
        else return left.top();
    }
};

相关推荐

  1. 】Leetcode 295. 数据位数【困难】

    2024-06-07 21:28:03       36 阅读
  2. 295. 数据位数

    2024-06-07 21:28:03       33 阅读
  3. 力扣295. 数据位数

    2024-06-07 21:28:03       70 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-06-07 21:28:03       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-06-07 21:28:03       106 阅读
  3. 在Django里面运行非项目文件

    2024-06-07 21:28:03       87 阅读
  4. Python语言-面向对象

    2024-06-07 21:28:03       96 阅读

热门阅读

  1. 二维数组知识点

    2024-06-07 21:28:03       23 阅读
  2. 大模型训练学习笔记

    2024-06-07 21:28:03       35 阅读
  3. RDMA (1)

    RDMA (1)

    2024-06-07 21:28:03      30 阅读
  4. C# using的几个用途

    2024-06-07 21:28:03       27 阅读
  5. web学习笔记(六十四)

    2024-06-07 21:28:03       26 阅读
  6. 中介子方程四

    2024-06-07 21:28:03       25 阅读
  7. 深入探索Spark MLlib:大数据时代的机器学习利器

    2024-06-07 21:28:03       29 阅读
  8. 【leetcode--两数之和(输入有序数组)】

    2024-06-07 21:28:03       32 阅读
  9. 14.2 golint工具、godoc工具、Makefile文件

    2024-06-07 21:28:03       31 阅读