首页 > leetcode-295 数据流的中位数

leetcode-295 数据流的中位数

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

例如,

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

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

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

void addNum(int num) - 从数据流中添加一个整数到数据结构中。

double findMedian() - 返回目前所有元素的中位数。

示例:

addNum(1)

addNum(2)

findMedian() -> 1.5

addNum(3)

findMedian() -> 2

针对该问题,由于数组是动态增加的,我们使用传统的查找中位数的方式为:有序数组取中间两位(奇数个数字,取中间一位数字;偶数个数字,取中间两个数字的平均值),那么每次我们增加一个数字就需要重新排序,代价太大

此时我们可以维护两个堆,最大堆存储较小元素,最小堆存储较大元素,且两个堆大小相差不能超过1;此时,我们仅需要每次调整两个堆的堆顶元素即可。

计算中位数时,根据两个堆各自的大小,分别取堆顶进行计算求值。该过程就是会出现重建堆较为耗时(O(nlogn))之外再没有需要消耗时间的地方了

实现如下:

class MedianFinder { 
public:/** initialize your data structure here. */MedianFinder() {  }void addNum(int num) { if (big_heap.empty()) { big_heap.push(num);} else { //当最大堆元素个数大于最小堆元素个数,此时需要向最小堆插入if(big_heap.size() > small_heap.size()) {  //但是发现插入的元素 小于 最大堆的元素个数//规则是:最小堆堆顶元素一定大于最大堆的堆顶,所以需要调整最大堆堆顶if (num < big_heap.top()) { small_heap.push(big_heap.top());big_heap.pop();big_heap.push(num);} else { small_heap.push(num);}} else { if (num > small_heap.top()) { big_heap.push(small_heap.top());small_heap.pop();small_heap.push(num);} else { big_heap.push(num);}}}}double findMedian() { if (big_heap.size() > small_heap.size()) { return big_heap.top();} else if (big_heap.size() == small_heap.size()) { return (double)(big_heap.top() + small_heap.top()) / 2.0;} else { return small_heap.top();}}
private:priority_queue<int, vector<int>, greater<int>> small_heap;priority_queue<int, vector<int>, less<int>> big_heap;
};

更多相关:

  • 前言 堆数据结构 使用的是优先级队列实现,创建堆的时候需要指定堆中元素的排列方式,即最大堆或者最小堆 最大堆即 堆顶元素为堆中最大的元素 最小堆即 堆顶元素为堆中最小堆元素 如下为一个最大堆 中位数: 一组数排序后,如果元素个数如下 奇数个数n:(int) n/2 的数 偶数个数n: (int) n/2 和(int) n/2...

  • 栈stack:stack 后入先出(LIFO) q.top()获取栈顶元素(并不删除)q.pop()删除栈顶元素q.push(x)向栈中加入元素q.empty()判断栈是否为空 队列queue:先入先出(FIFO)   q.front()获取队首元素(并不删除)q.pop()删除队首元素q.push(x)向队列中加入元素q....

  • resize(),设置大小(size); reserve(),设置容量(capacity); size()是分配容器的内存大小,而capacity()只是设置容器容量大小,但并没有真正分配内存。 打个比方:正在建造的一辆公交车,车里面可以设置40个座椅(reserve(40);),这是它的容量,但并不是说它里面就有了40个座椅,只能说...

  • v-for="(index,$i) in total" :key="$i":style="{left:`${itemWidth*((index-1)%rowItemCount)}px`,top:`${itemHeight*(Math.ceil(index/rowItemCount)-1)}px`}" //total是显示总数量 //l...

  •   技巧一(推荐指数★★★★★) 采用top、right、bottom、left,可以不在乎父元素的宽度和高度,对GPU损耗低于技巧三,但是对浏览器内存的消耗高于技巧三 .子元素 {/*父元素需要position: relative|absolute;*/position: absolute;margin: auto;to...

  • 设计一个支持 push,pop,top 操作,并能在常数时间内检索到最小元素的栈。 push(x) – 将元素 x 推入栈中。pop() – 删除栈顶的元素。top() – 获取栈顶元素。getMin() – 检索栈中的最小元素。 示例: MinStack minStack = new MinStack(); minStack...