作者: 负雪明烛
id: fuxuemingzhu
个人博客: http://fuxuemingzhu.cn/


题目地址:https://leetcode.com/problems/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 middle value. So the median is the mean of the two middle value.

For example,

[2,3,4], the median is 3

[2,3], the median is (2 + 3) / 2 = 2.5

Design a data structure that supports the following two operations:

  • void addNum(int num) - Add a integer number from the data stream to the data structure.
  • double findMedian() - Return the median of all elements so far.

Example:

addNum(1)
addNum(2)
findMedian() -> 1.5
addNum(3)
findMedian() -> 2

Follow up:

  1. If all integer numbers from the stream are between 0 and 100, how would you optimize it?
  2. If 99% of all integer numbers from the stream are between 0 and 100, how would you optimize it?

题目大意

求一个数据流的中位数。

解题方法

大根堆+小根堆

让我们找到一个无线数据流中的中位数。心路历程如下:

  • 我们如果能排序,就能找到中位数 ==> 排序时间复杂度太高,不可
  • 把数据集划分成两部分,一半比中位数小,一半比中位数大 ==> 数据分为两部分
  • 只需要知道比中位数小的那部分的最大值和比中位数大的那部分的最小值 ==> 大根堆和小根堆

所以,使用了两个堆:lesser表示比中位数小的那部分,因为要找出这部分的最大值,所以需要是大根堆;larger表示比中位数大的那部分,因为要找出这部分的最小值,所以需要时小根堆。

约定:如果数据流长度是偶数,则lesser的数字个数和larger相等;如果数据流长度是奇数,则多余的那个数字放到lesser中。即lesser.size() - larger.size() <= 1。

每个数字进来的时候,先放入lesser中,把lesser中的最大值拿出来放到larger中,此时larger会和less一样多,或者larger比lesser多一个。当larger比lesser多一个时,把larger中的最小值拿出来放到lesser中,从而保证lesser.size() - larger.size() <= 1;。

如果lesser和larger两者数据个数相等,则中位数是lesser中的最大值和larger中的最小值的平均值;如果lesser比larger多一个,那么中位数是lesser中的最大值。

注意C++中,priority_queue默认是大根堆,小根堆的定义方法是priority_queue<double, vector<double>, greater<double>>

C++代码如下:

class MedianFinder {
public:
/** initialize your data structure here. */
MedianFinder() {
} void addNum(int num) {
lesser.push(num);
larger.push(lesser.top());
lesser.pop();
if (larger.size() > lesser.size()) {
lesser.push(larger.top());
larger.pop();
}
} double findMedian() {
return lesser.size() == larger.size() ? (lesser.top() + larger.top()) / 2 : lesser.top();
}
private:
// 存放比中位数小的数字,大根堆
priority_queue<double> lesser;
// 存放比中位数大的数字,小根堆
priority_queue<double, vector<double>, greater<double>> larger;
}; /**
* Your MedianFinder object will be instantiated and called as such:
* MedianFinder* obj = new MedianFinder();
* obj->addNum(num);
* double param_2 = obj->findMedian();
*/

参考资料:https://www.cnblogs.com/grandyang/p/4896673.html

日期

2019 年 9 月 15 日 —— 中秋假期的最后一天啦,刷题加油~

【LeetCode】295. Find Median from Data Stream 解题报告(C++)的更多相关文章

  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. LeetCode——295. Find Median from Data Stream

    一.题目链接: https://leetcode.com/problems/find-median-from-data-stream 二.题目大意: 给定一段数据流,要求求出数据流中的中位数,其中数据 ...

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

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

  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. nginx二级域名指向不同文件项目配置

    需要使用泛域名解析, 并且加上空的判断,以保证没有二级域名的也可以访问 核心配置 server_name ~^(?<subdomain>.+)\.caipudq\.cn$;if ( $su ...

  2. (转载) Java多线程技术

    多线程编程一直是学员们比较头痛和心虚的地方,因为线程执行顺序的不可预知性和调试时候的困难,让不少人在面对多线程的情况下选择了逃避,采用单线程的方式,其实只要我们对线程有了明确的认识,再加上java内置 ...

  3. 解决CentOS7 docker容器映射端口只监听ipv6的问题

    问题现象 docker容器起来以后,查看9100端口监听情况,如下图: $ ss -lntp State Recv-Q Send-Q Local Address:Port Peer Address:P ...

  4. c++string转const char*与char*

    #include <iostream> #include <string> #include <memory> using namespace std; const ...

  5. 复制virtualbox虚拟硬盘

    D:\VirtualBox\VBoxManage.exe clonevdi F:\virtualbox\rac1\rac1.vdi F:\virtualbox\rac2\rac2.vdi 虚拟机软件安 ...

  6. LINUX 系统性能检测工具vmstat

    vmstat 有2个参数,第一个是采样时间间隔(单位是s),第二个参数是采样个数. #表示 2s采样一次,一共采样2次 vmstat 2 2 也可以只写第一个参数,让系统一直采样直到停止(ctrl + ...

  7. Shell脚本实现乱序排列文件内容的多种方法(洗牌问题)

    洗牌问题:洗一副扑克,有什么好办法?既能洗得均匀,又能洗得快?即相对于一个文件来说怎样高效率的实现乱序排列? ChinaUnix 确实是 Shell 高手云集的地方,只要你想得到的问题,到那里基本上都 ...

  8. Synchronized深度解析

    概览: 简介:作用.地位.不控制并发的影响 用法:对象锁和类锁 多线程访问同步方法的7种情况 性质:可重入.不可中断 原理:加解锁原理.可重入原理.可见性原理 缺陷:效率低.不够灵活.无法预判是否成功 ...

  9. elasticSearch索引库查询的相关方法

    package com.hope.es;import org.elasticsearch.action.search.SearchResponse;import org.elasticsearch.c ...

  10. Appium获取toast消息遇到的问题(一)

    一.运行错误 Android获取toast,需要在参数里设置automationName:Uiautomator2 1 # 设置设备的信息 2 desired_caps = { 3 'platform ...