问题描述

如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。

例如,

[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、findMedia进行 50000 次调用。

问题分析

使用一个大顶堆和一个小顶堆,其中小顶堆中的数据永远大于大顶堆中的数据(这样左端大顶堆的堆顶就是左半部分最大值,右端小顶堆的堆顶就是右半部分最小值),并且使得小顶堆中元素个数要么等于大顶堆中元素个数,要么比大顶堆中元素个数少一个,第一个情形返回两个堆顶的平均值,第二种情况返回大顶堆的堆顶元素即可。

代码

class MedianFinder {
private:
priority_queue<int,vector<int>,greater<int>> rightq;//小顶堆
priority_queue<int,vector<int>,less<int>> leftq;//大顶堆
public:
/** initialize your data structure here. */
MedianFinder() { } void addNum(int num) {
//此时要使leftq.size()==rightq.size()+1,将新元素放入小顶堆后,取出堆顶元素放入大顶堆
if(leftq.size() == rightq.size())
{
rightq.push(num);
leftq.push(rightq.top());
rightq.pop();
}
//此时leftq.size()==rightq.size()+1,要使两个堆元素个数相等,先把新元素放入大顶堆找出新的大顶堆最大元素放入小顶堆
else{
leftq.push(num);
rightq.push(leftq.top());
leftq.pop();
}
} double findMedian() {
if(leftq.size() == rightq.size())
{
return (leftq.top()+rightq.top())/2.0;
}
else{
return leftq.top();
}
}
}; /**
* Your MedianFinder object will be instantiated and called as such:
* MedianFinder* obj = new MedianFinder();
* obj->addNum(num);
* double param_2 = obj->findMedian();
*/

结果

执行用时 :280 ms, 在所有 C++ 提交中击败了46.21%的用户
内存消耗 :41.6 MB, 在所有 C++ 提交中击败了100.00%的用户

注意priority_queue使用基本数据类型时,只需要传入数据类型,默认是大顶堆。

《剑指offer》面试题41. 数据流中的中位数的更多相关文章

  1. 剑指offer(63)数据流中的中位数

    题目描述 如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值.如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值.我们 ...

  2. 【剑指Offer】63、数据流中的中位数

      题目描述:   如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值.如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平 ...

  3. 剑指Offer:面试题15——链表中倒数第k个结点(java实现)

    问题描述 输入一个链表,输出该链表中倒数第k个结点.(尾结点是倒数第一个) 结点定义如下: public class ListNode { int val; ListNode next = null; ...

  4. 剑指offer系列37----数据流中的中位数

    [题目]如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值, * 那么中位数就是所有数值排序之后位于中间的数值. package com.exe8.offer; import java.uti ...

  5. 剑指offer 面试题64 数据流的中位数

    struct cmp { bool operator()(double a, double b) { return a > b; } }; class Solution { public: vo ...

  6. 剑指Offer:面试题29——数组中出现次数超过一半的数字(java实现)

    PS:在前几天的面试中,被问到了这个题.然而当时只能用最低效的方法来解. 问题描述: 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2, ...

  7. 剑指offer 面试题 删除链表中重复的节点

    题目描述 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针. 例如,链表1->2->3->3->4->4->5 处理后 ...

  8. 剑指offer 面试题56. 数组中只出现一次的两个数字

    题目描述 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. 方法1:用set记录出现过的数字 class Solution { public: void F ...

  9. 剑指 Offer 41. 数据流中的中位数 + 堆 + 优先队列

    剑指 Offer 41. 数据流中的中位数 Offer_41 题目详情 题解分析 本题使用大根堆和小根堆来解决这个寻找中位数和插入中位数的问题. 其实本题最直接的方法是先对数组进行排序,然后取中位数. ...

随机推荐

  1. CF1099A Snowball 题解

    Content 有一个重量为 \(w\) 的雪球从高度为 \(h\) 的位置开始滚落,每秒它的高度会减少 \(1\),同时在高度为 \(i\) 的位置它的重量会增加 \(i\).在雪球滚动的路线上还有 ...

  2. CF897B Chtholly's request 题解

    Content 我们将长度为偶数的回文数称作 zcy 数,比如 \(11,1221\) 是 zcy 数,而 \(34,121\) 不是.假设第 \(i\) 个 zcy 数为 \(a_i\),求 \(\ ...

  3. LuoguP7259 [COCI2009-2010#3] SORT 题解

    Content 请编写一个"频率排序器".输入一个 长度为 \(n\) 的数列 \(A=\{a_1,a_2,\dots,a_n\}\),要求: 按照每个数的出现次数降序排列. 如果 ...

  4. IDEA微服务项目SpringBoot一键(批量)顺序启动

    找到 搜索 RunDashboard <option name="configurationTypes"> <set> <option value=& ...

  5. JAVAWEB项目报"xxx响应头缺失“漏洞处理方案

    新增一个拦截器,在拦截器doFilter()方法增加以下代码 public void doFilter(ServletRequest request, ServletResponse response ...

  6. 【LeetCode】376. Wiggle Subsequence 解题报告(Python)

    [LeetCode]376. Wiggle Subsequence 解题报告(Python) 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.c ...

  7. 【LeetCode】423. Reconstruct Original Digits from English 解题报告(Python)

    [LeetCode]423. Reconstruct Original Digits from English 解题报告(Python) 标签: LeetCode 题目地址:https://leetc ...

  8. 【LeetCode】836. Rectangle Overlap 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地址:https://leetcode.com/problems/rectangle ...

  9. 1021 - Painful Bases

    1021 - Painful Bases   PDF (English) Statistics Forum Time Limit: 2 second(s) Memory Limit: 32 MB As ...

  10. SpringMVC 五大组件

    DispatcherServlet HandleMapping Controller ModeAndView ViewResolver 1.DispatcherServlet 这个控件是SpringM ...