infrastructureDataStructure9

题目描述[原题链接][https://leetcode-cn.com/problems/find-median-from-data-stream/]

中位数是有序列表中间的数。如果列表长度是偶数,中位数则是中间两个数的平均值。

例如,

[2,3,4] 的中位数是 3

[2,3] 的中位数是 (2 + 3) / 2 = 2.5

设计一个支持以下两种操作的数据结构:

  • void addNum(int num) - 从数据流中添加一个整数到数据结构中。
  • double findMedian() - 返回目前所有元素的中位数。

示例:

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

进阶:

  1. 如果数据流中所有整数都在 0 到 100 范围内,你将如何优化你的算法?
  2. 如果数据流中 99% 的整数都在 0 到 100 范围内,你将如何优化你的算法?

算法描述

创建一个向量,每进来一个元素,先判断当前向量是否为空,向量为空,直接添加元素至向量中,不为空,找到比当前元素小的第一个元素,通过lower_bound()函数即可,将当前元素插入,使每次进入后,向量中的元素仍然有序,当要找中位数时,分奇偶,分别返回结果;

C++代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class MedianFinder {
public:
vector<int> nums;
double median=0;
/** initialize your data structure here. */
MedianFinder() {
}

void addNum(int num) {
if(nums.empty())
nums.push_back(num);
else nums.insert(lower_bound(nums.begin(),nums.end(),num),num);
}

double findMedian() {
int t = nums.size()/2;
if(nums.size()%2==0){
median = (nums[t]+nums[t-1])/2.0;
}else median = nums[t]*1.0;
return median;
}
};

/**
* Your MedianFinder object will be instantiated and called as such:
* MedianFinder* obj = new MedianFinder();
* obj->addNum(num);
* double param_2 = obj->findMedian();
*/

Java代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
class MedianFinder {

private int count;
private PriorityQueue<Integer> maxheap;
private PriorityQueue<Integer> minheap;

/** initialize your data structure here. */
public MedianFinder() {
count = 0;
maxheap = new PriorityQueue<>((x,y)->y-x);
minheap = new PriorityQueue<>();
}

public void addNum(int num) {
count +=1;
maxheap.offer(num);
minheap.add(maxheap.poll());
if((count&1)!=0){
maxheap.add(minheap.poll());
}
}

public double findMedian() {
if((count&1)==0){
return (double)(maxheap.peek()+minheap.peek())/2;
}else{
return (double)maxheap.peek();
}
}
}

/**
* Your MedianFinder object will be instantiated and called as such:
* MedianFinder obj = new MedianFinder();
* obj.addNum(num);
* double param_2 = obj.findMedian();
*/