LeetCode——295. Find Median from Data Stream
一.题目链接:
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的更多相关文章
- [LeetCode] 295. Find Median from Data Stream ☆☆☆☆☆(数据流中获取中位数)
295. Find Median from Data Stream&数据流中的中位数 295. Find Median from Data Stream https://leetcode.co ...
- leetcode@ [295]Find Median from Data Stream
https://leetcode.com/problems/find-median-from-data-stream/ Median is the middle value in an ordered ...
- [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 ...
- [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 ...
- 剑指offer 最小的k个数 、 leetcode 215. Kth Largest Element in an Array 、295. Find Median from Data Stream(剑指 数据流中位数)
注意multiset的一个bug: multiset带一个参数的erase函数原型有两种.一是传递一个元素值,如上面例子代码中,这时候删除的是集合中所有值等于输入值的元素,并且返回删除的元素个数:另外 ...
- 【LeetCode】295. Find Median from Data Stream 解题报告(C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 大根堆+小根堆 日期 题目地址:https://le ...
- 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 ...
- [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 ...
- 295 Find Median from Data Stream 数据流的中位数
中位数是排序后列表的中间值.如果列表的大小是偶数,则没有中间值,此时中位数是中间两个数的平均值.示例:[2,3,4] , 中位数是 3[2,3], 中位数是 (2 + 3) / 2 = 2.5设计一个 ...
随机推荐
- 如何将本地的文件上传到你的github仓库中(首次流程)
1.(先进入项目文件夹,右键项目文件夹,选择git Bash)通过命令 git init 把这个目录变成git可以管理的仓库 git init 2.把文件添加到版本库中,使用命令 git add . ...
- 学习小片段——thymeleaf入门
1: 概述 thymeleaf是一个跟 Velocity.FreeMarker 类似的模板引擎,和以前学的jsp相近,但性能上无疑是比jsp好. 参考文档官方文档:https://www.thymel ...
- python学习第二次笔记
python学习第二次记录 1.格式化输出 name = input('请输入姓名') age = input('请输入年龄') height = input('请输入身高') msg = " ...
- Linux运维工程师应具备哪些技能?
对于我们这些刚入门的运维小白来说,极强的好奇心总会驱使我们去涉猎各种技术,弄到最后很可能该学的知识半懵半解,知识体系混乱,学习毫无章法.因此,我们学习 时要有一个明确的目标和知识体系(也是我学习的 ...
- JDBC 链接mysql 8 的问题
转载:jdbc连接mysql 8 的一些坑 1.驱动包要升级为 mysql-connector-java-8.0.11.jar 2.JDBC driver 由“com.mysql.jdbc.Drive ...
- TCP/UDP 网络工具
1. 统计连接状态 netstat -n | awk '/^tcp/ {++State[$NF]} END {for(s in State) print s, State[s]}' CLOSE_WAI ...
- ros 使用笔记
1. publishers/subscribers 常用指令 说明rosnode list 查看所有激活的节点rostopic list 查看所有激活的topicrostopic i ...
- 【linux基础】ubuntu系统NVIDIA驱动安装
在安装GPU环境下的软件工具,特别是CUDA/CUDNN等,一定要先把GPU环境搭建好. NVIDIA驱动安装会遇到各种问题,真希望黄教主可以将各个工具如何安装使用讲解的更加细致.清楚一些,有时候按照 ...
- Git入门(安装及基础命令行操作)
一.安装 1.Mac 在Mac中安装Git的方法不止一种.最简单的要数通过Xcode命令行工具.对于Mavericks(10.9)或更高版本的操作系统,当你第一次尝试在终端执行git命令时,系统会自动 ...
- 20175120彭宇辰 《Java程序设计》第六周学习总结
教材学习内容总结 第七章 一.内部类与外部类的关系 1.内部类可以使用外嵌类的成员变量和方法.2.类体中不可以声明类变量和类方法,外部类可以用内部类声明对象.3.内部类仅供外嵌类使用.4.类声明可以使 ...