剑指offer63:数据流中的中位数

题目描述:

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

本题最开始简单的理解为求中位数,使用的是快排的思想,当数据元素为奇数个时,求第n/2大的数,当元素个数为偶数时,先求n/2个数,然后对右边的求出一个最小值。

看了别人的做法,发现应该把这道题理解为一个在线算法题。关键是使用两个堆,最大化堆存储前n/2个数,最小化堆存储后n/2个数,当元素个数为偶数个时,元素num放入最小化堆中;元素个数为奇数时,元素num放入最大化堆。最终,当元素个数为奇数时,中位数就是最小化堆的堆顶;当元素个数为偶数时,中位数是最小化堆和最大化堆的堆顶的均值。

 1 class Solution {
 2     private:
 3         vector<int> minHeap; //数组中的后一半元素组成一个最小化堆
 4         vector<int> maxHeap; //数组中的前一半元素组成一个最大化堆
 5     public:
 6         void Insert(int num) {
 7             if(((minHeap.size()+maxHeap.size()) & 1) == 0) {  //偶数数据的情况下,则在最小堆中插入元素
 8                 if(maxHeap.size() > 0 && num < maxHeap[0]) {
 9                     maxHeap.push_back(num);
10                     push_heap(maxHeap.begin(), maxHeap.end(), less<int>());
11                     num=maxHeap[0];
12                     pop_heap(maxHeap.begin(), maxHeap.end(), less<int>());
13                     maxHeap.pop_back();
14                 }
15                 minHeap.push_back(num); //把前一半找到的最大值放到后一半中
16                 push_heap(minHeap.begin(), minHeap.end(), greater<int>());
17             } else {
18                 if(minHeap.size() > 0 && num > minHeap[0]) {   //奇数数据的情况下,则在最大堆中插入元素
19                     minHeap.push_back(num);
20                     push_heap(minHeap.begin(), minHeap.end(), greater<int>());
21                     num=minHeap[0];
22                     pop_heap(minHeap.begin(), minHeap.end(), greater<int>());
23                     minHeap.pop_back();
24                 }
25                 maxHeap.push_back(num); //把后一半找到的最大值放到前一半中
26                 push_heap(maxHeap.begin(), maxHeap.end(), less<int>());
27             }
28         }
29
30         double GetMedian() {
31             int size=minHeap.size() + maxHeap.size();
32             if(size==0) return -1;
33             if((size&1) != 0) {
34                return (double) minHeap[0];
35             } else {
36                return (double) (maxHeap[0] + minHeap[0]) / 2;
37             }
38         }
39 };
时间: 2024-12-29 23:29:48

剑指offer63:数据流中的中位数的相关文章

剑指Offer——数据流中的中位数

题目描述: 如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值.如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值. 分析: 插入排序. 代码: 1 class Solution { 2 public: 3 vector<int> v; 4 int vSize = 0; 5 void Insert(int num) { 6 v.push_back(num); 7 for(int i = vSize - 1; i

剑指:数据流中的中位数

题目描述 如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值.如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值.我们使用Insert()方法读取数据流,使用GetMedian()方法获取当前读取数据的中位数. 解法 利用大根堆存放较小的一半元素,小根堆存放较大的一半元素.维持大小堆的元素个数差不超过 1. import java.util.Comparator; import java.util.Priority

[剑指Offer] 62.数据流中的中位数

题目描述 如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值.如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值. 1 class Solution { 2 public: 3 vector<int> vec; 4 void Insert(int num) 5 { 6 vec.push_back(num); 7 } 8 9 double GetMedian() 10 { 11 sort(vec.begin(),v

剑指offer(六十三)之数据流中的中位数

题目描述 如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值.如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值. 代码: import java.util.*; public class Solution { ArrayList<Integer> al = new ArrayList<Integer>(); public void Insert(Integer num) { al.add(num);

数据流中的中位数-剑指Offer

数据流中的中位数 题目描述 如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值.如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值. 思路 我们可以用数组存,每次取中位数时需要排序 我们也可以用平衡二叉树存,不过构造树的过程很复杂 我们也可以用大小堆存,不过也不简单 最后我选择用java里现成的ArrayList存,用Collections.sort()方法排序 代码 import java.util.ArrayL

《剑指offer》:[64]数据流中的中位数

题目:如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值.如果从数据流中读出偶数个数值,那么中位数就是所有数据排序后中间两个数的平均值. 例如:1,2,3,4,5的中位数为:3.1,2,3,4的中位数为:(2+3)/2=3. 方案一:采用Partition来解决.在[29]中我们讲过,快速查找中的Partition函数是十分重要,是一个比较常用的算法.所以这里我们采用partion函数来解决.从字符流里读字符,插入到一个无需的数组中的复杂度为

《剑指offer》数据流中的中位数

[ 声明:版权所有,转载请标明出处,请勿用于商业用途.  联系信箱:[email protected]] 题目链接:http://www.nowcoder.com/practice/9be0172896bd43948f8a32fb954e1be1?rp=4&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking 题目描述 如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后

[剑指offer] 63. 数据流中的中位数

题目描述 如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值.如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值.我们使用Insert()方法读取数据流,使用GetMedian()方法获取当前读取数据的中位数. 用一个大顶堆和一个小顶堆,维持大顶堆的数都小于等于小顶堆的数,且两者的个数相等或差1.平均数就在两个堆顶的数之中. 原文地址:https://www.cnblogs.com/ruoh3kou/p/10261

剑指offer:数据流中的中位数

题目描述: 如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值.如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值.我们使用Insert()方法读取数据流,使用GetMedian()方法获取当前读取数据的中位数. 思路分析: 思路一:最朴素的想法,用一个vector来存输入的数据流.在取中位数的函数中,每次对数据流进行一次排序,对于奇数长度的数据,直接取中间值,对于偶数长度的数据,取中间两个数的平均值.很显然,这个