一.题目链接:

  https://leetcode.com/problems/find-median-from-data-stream

二.题目大意:

  给定一段数据流,要求求出数据流中的中位数,其中数据流是动态变化的。如果数据流中的数字个数是奇数的话,则中位数是中间位置的数字;如果数据流中的数字是偶数的话,则中位数是排序好的数据流中的中间两个数的的平均值。

三.题解:

  如果数据流是静态不变的话,此时问题是比较好求解的。但是数据流是动态变化的,所以数据流中每次进入一个新的数字时,都要保证能够高效的找到数据流的中位数。我们可以这么考虑:如果把数据流中的数字分为个数相同的两部分的话(假设为A和B,其中A中的数字全部小于B中的数字),那么我们所求的中位数,实质就是A中的最大值和B中的最小值的平均值。因此,我们可以用两个堆来表示这个过程,其中大顶堆maxH存储的是数据流中的数值较小的数字,而小顶堆minH存储的是数据六中数值较大的数字,且maxH中的数字全部小于minH中的数字。并且堆可以快速的找出其中的最值,所以可以快速找得到minH中的最小值和maxH中的最大值,从而求出中位数。代码如下:

#include<iostream>
#include<unordered_map>
#include<queue>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<sstream>
#include<set>
#include<map>
#include<stack>
#define MAX_NUM 100
using namespace std;
class MedianFinder {
public:
/** initialize your data structure here. */
priority_queue<int,vector<int>,less<int>> maxH;//定义大顶堆,用于存储较小的数据部分
priority_queue<int,vector<int>,greater<int>> minH;//定义小顶堆,用于存储较大的数据部分
MedianFinder() { } void addNum(int num) {
maxH.push(num);
int tmp = maxH.top();
maxH.pop();
minH.push(tmp);//保证小顶堆中的数据大于大顶堆中的数据
if(minH.size() > maxH.size())
{
int tmp = minH.top();
minH.pop();
maxH.push(tmp);//保证大顶堆中的数据小于小顶堆中的数据
} } double findMedian() {
if(minH.size() == maxH.size())//如果两个堆的大小相同,则返回它们最值的平均值
return (minH.top() + maxH.top()) / 2.0;
return minH.size() > maxH.size() ? minH.top() : maxH.top();//如果两个堆的大小不相同,返回数字个数多的堆的最值
}
}; /**
* Your MedianFinder object will be instantiated and called as such:
* MedianFinder obj = new MedianFinder();
* obj.addNum(num);
* double param_2 = obj.findMedian();
*/ int main()
{
MedianFinder test = MedianFinder();
test.addNum(1);
test.addNum(2);
test.addNum(3);
test.addNum(4);
test.addNum(5);
cout<<test.findMedian()<<endl; }

每次从数据流中找出中位数的时间为O(1),调整两个堆的时间为O(logN),对于含有n个数字的数据流,总的时间复杂度为O(NlogN),空间复杂度为O(N)。

此外,有几个点需要注意下:

1.代码中使用了priority_queue即优先队列来实现堆,因为优先队列获取优先级最高的值所需时间为O(1),调整的过程为O(logN),与堆的操作时间类似,能较好的模拟堆。

2.通常情况下,堆默认的优先级最高的值是指的最大值,也可以是最小值,不过需要显式的说明(见本例中优先队列的定义)。

3.要保证最小堆中存储的始终是较大的数值,而大顶堆中存储的是较小的数值。所以才会有addNum中的那些操作。

LeetCode——295. Find Median from Data Stream的更多相关文章

  1. [LeetCode] 295. Find Median from Data Stream ☆☆☆☆☆(数据流中获取中位数)

    295. Find Median from Data Stream&数据流中的中位数 295. Find Median from Data Stream https://leetcode.co ...

  2. leetcode@ [295]Find Median from Data Stream

    https://leetcode.com/problems/find-median-from-data-stream/ Median is the middle value in an ordered ...

  3. [LeetCode] 295. Find Median from Data Stream 找出数据流的中位数

    Median is the middle value in an ordered integer list. If the size of the list is even, there is no ...

  4. [leetcode]295. Find Median from Data Stream数据流的中位数

    Median is the middle value in an ordered integer list. If the size of the list is even, there is no ...

  5. 剑指offer 最小的k个数 、 leetcode 215. Kth Largest Element in an Array 、295. Find Median from Data Stream(剑指 数据流中位数)

    注意multiset的一个bug: multiset带一个参数的erase函数原型有两种.一是传递一个元素值,如上面例子代码中,这时候删除的是集合中所有值等于输入值的元素,并且返回删除的元素个数:另外 ...

  6. 【LeetCode】295. Find Median from Data Stream 解题报告(C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 大根堆+小根堆 日期 题目地址:https://le ...

  7. 295. Find Median from Data Stream

    题目: Median is the middle value in an ordered integer list. If the size of the list is even, there is ...

  8. [LC] 295. Find Median from Data Stream

    Median is the middle value in an ordered integer list. If the size of the list is even, there is no ...

  9. 295 Find Median from Data Stream 数据流的中位数

    中位数是排序后列表的中间值.如果列表的大小是偶数,则没有中间值,此时中位数是中间两个数的平均值.示例:[2,3,4] , 中位数是 3[2,3], 中位数是 (2 + 3) / 2 = 2.5设计一个 ...

随机推荐

  1. Fescar: Fast & Easy Commit And Rollback

    Fescar is an easy-to-use, high-performance, java based, open source distributed transaction solution ...

  2. openSUSE XFCE桌面 多媒体解码器安装

    openSUSE15 leap 在终端命令行安装编解码器: 添加必要的软件源 zypper addrepo -f http://packman.inode.at/suse/openSUSE_Leap_ ...

  3. 移动终端设备ID

    转自:https://wetest.qq.com/lab/view/116.html 一.前言 对于移动端产品的常规统计分析和运营推广,渠道结算来说,能精准的识别区分并且跟踪一台终端设备(一个终端用户 ...

  4. Java中String类常用方法(字符串中的子字符串的个数)

    重点内容 4种方法: 1.int indexOf(String str)返回第一次出现的指定子字符串在此字符串中的索引. 2.int indexOf(String str, int startInde ...

  5. Mesh内存分配器的mmap小技巧

    最近看了一篇内存分配器的论文,原理很简单,但是里面的数学论证还没看懂,这次先简单写一下原理和用到的API. 内存分配器是用于封装操作系统提供的底层API,给应用程序提供动态内存的.内存不断申请释放后, ...

  6. 安装系统后IP配置问题

    1.配置静态IP 在/etc/sysconfig/network-script/ifcfg-eth0 文件,网卡管理文件.修改为静态IP.IPADDR.网关.掩码等 同一台机器上的网卡不能配置在同一网 ...

  7. Windows Server 2012配置iis遇到的问题

    发布网站访问时报500 - 内部服务器错误,经排查是Windows Server 2012上的iis配置有问题,有些需要的功能没有配置. 在重新配置iis时总是安装失败,提示存储空间不足. 在网上查找 ...

  8. SpringBoot框架中,使用过滤器进行加密解密操作(一)

    一.基本说明 1.请求方式:POST请求.注解@PostMapping 2.入参格式:json串 3.出参格式:json串(整体加密) 4.使用Base64进行加密解密.具体的加密方式,可以根据需求自 ...

  9. PAT乙级考前总结(一)

    数学相关的题目 1001 害死人不偿命的(3n+1)猜想 (15 分) 直接一步步计数 1005 继续(3n+1)猜想 (25 分) 卡拉兹(Callatz)猜想已经在1001中给出了描述.在这个题目 ...

  10. word2007无法打开.doc

    如果您的WORD2007无法打开.DOC文档,可以试试如下的方法 打开注册表编辑器(开始-运行-输入regedit VISTA中在开始菜单最下方的搜索栏内输入regedit) 展开HKEY_CLASS ...