[题解]剑指 Offer 41. 数据流中的中位数(C++)
2021/8/27 20:37:03
本文主要是介绍[题解]剑指 Offer 41. 数据流中的中位数(C++),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
题目
如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。
例如,
[2,3,4] 的中位数是 3
[2,3] 的中位数是 (2 + 3) / 2 = 2.5
设计一个支持以下两种操作的数据结构:
void addNum(int num) - 从数据流中添加一个整数到数据结构中。
double findMedian() - 返回目前所有元素的中位数。
示例 1:
输入: ["MedianFinder","addNum","addNum","findMedian","addNum","findMedian"] [[],[1],[2],[],[3],[]] 输出:[null,null,null,1.50000,null,2.00000]
示例 2:
输入: ["MedianFinder","addNum","findMedian","addNum","findMedian"] [[],[2],[],[3],[]] 输出:[null,null,2.00000,null,2.50000]
限制:
- 最多会对 addNum、findMedian 进行 50000 次调用。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/shu-ju-liu-zhong-de-zhong-wei-shu-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
这题考察的就是使用什么样的数据结构来存数据流的数并且排序。如果使用vector,那么每次插入新数排序都很麻烦,虽然利用二分查找确认要插入的位置只需要时间复杂度O(log(n)),但是需要将插入位置之后的元素全部往后移动;利用有序数据结构,我想到的是优先队列(堆),即STL中的priority_queue,关于priority_queue具体说明可以参考这里:https://en.cppreference.com/w/cpp/container/priority_queue
只用一个优先队列虽然可以解决插入数据的问题,但是要查找中位数却很麻烦,难道每次查找要pop掉一半的数据出来再插回去?解决方案也很简单:用两个优先队列。一个是大根堆,一个是小根堆,保证大根堆堆顶元素比小根堆堆顶元素还要小,同时两个堆的元素数量一样或者只相差1,如果它们数量一样,那么中位数就是两个堆堆顶元素的均值;如果不一样,那就是多1个的那个堆的堆顶元素。为了方便,可以在插入数据时设计保持其中一个堆的元素数量不少于另一个堆。
每次添加新元素的时间复杂度是O(n),查询中位数的时间复杂度则是O(1),空间复杂度O(n)。
代码
class MedianFinder { public: /** initialize your data structure here. */ MedianFinder() { } void addNum(int num) { small.push(num); large.push(small.top()); small.pop(); if(large.size() > small.size()) { small.push(large.top()); large.pop(); } } double findMedian() { return small.size() > large.size() ? small.top() : (small.top() + large.top())/2.0; } private: priority_queue<int, vector<int>, less<int>> small; priority_queue<int, vector<int>, greater<int>> large; }; /** * Your MedianFinder object will be instantiated and called as such: * MedianFinder* obj = new MedianFinder(); * obj->addNum(num); * double param_2 = obj->findMedian(); */
这篇关于[题解]剑指 Offer 41. 数据流中的中位数(C++)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-05-15PingCAP 黄东旭参与 CCF 秀湖会议,共探开源教育未来
- 2024-05-13PingCAP 戴涛:构建面向未来的金融核心系统
- 2024-05-09flutter3.x_macos桌面os实战
- 2024-05-09Rust中的并发性:Sync 和 Send Traits
- 2024-05-08使用Ollama和OpenWebUI在CPU上玩转Meta Llama3-8B
- 2024-05-08完工标准(DoD)与验收条件(AC)究竟有什么不同?
- 2024-05-084万 star 的 NocoDB 在 sealos 上一键起,轻松把数据库编程智能表格
- 2024-05-08Mac 版Stable Diffusion WebUI的安装
- 2024-05-08解锁CodeGeeX智能问答中3项独有的隐藏技能
- 2024-05-08RAG算法优化+新增代码仓库支持,CodeGeeX的@repo功能效果提升