剑指offer(C++)-JZ41:数据流中的中位数(算法-排序)
发布人:shili8
发布时间:2024-11-17 14:44
阅读次数:0
**剑指Offer-JZ41: 数据流中的中位数**
在这个问题中,我们需要实现一个数据流类,能够实时计算出当前数据流中的中位数。中位数是指如果数据流中的数字按顺序排列,则中间的那个数字。如果数据流中的数字总数为奇数,则中位数就是中间的那个数字;如果数据流中的数字总数为偶数,则中位数是中间两个数字的平均值。
**算法思路**
由于需要实时计算中位数,我们不能简单地将所有数据都存储在内存中,然后再进行排序和求中位数。这样做会导致空间复杂度过高,甚至可能导致内存溢出。
一种解决方案是使用一个大小为 n 的堆(大顶堆或小顶堆)来存储当前数据流中的数字,其中 n 是当前数据流中的数字总数。如果 n 为奇数,则中位数就是堆顶的数字;如果 n 为偶数,则中位数是堆顶和堆第二大的数字的平均值。
**C++代码实现**
cpp#include <iostream>
#include <vector>
class MedianFinder {
public:
// 大顶堆,存储当前数据流中的小于或等于当前中位数的数字 std::priority_queue<int> maxHeap;
// 小顶堆,存储当前数据流中的大于当前中位数的数字 std::priority_queue<int, std::vector<int>, std::greater<int>> minHeap;
void addNum(int num) {
// 如果 maxHeap 中的数字总数小于或等于 minHeap 中的数字总数,则将 num 加入 maxHeap if (maxHeap.size() <= minHeap.size()) {
maxHeap.push(num);
} else {
minHeap.push(num);
}
//重新调整堆,确保 maxHeap 和 minHeap 中的数字总数相等 balanceHeaps();
}
double findMedian() {
if (maxHeap.empty() && minHeap.empty()) {
return0.0;
} else if (maxHeap.size() == minHeap.size()) {
// 如果 maxHeap 和 minHeap 中的数字总数相等,则中位数是 maxHeap 和 minHeap 的堆顶数字的平均值 return (double)(maxHeap.top() + minHeap.top()) /2.0;
} else if (maxHeap.size() > minHeap.size()) {
// 如果 maxHeap 中的数字总数大于 minHeap 中的数字总数,则中位数是 maxHeap 的堆顶数字 return maxHeap.top();
} else {
// 如果 minHeap 中的数字总数大于 maxHeap 中的数字总数,则中位数是 minHeap 的堆顶数字 return minHeap.top();
}
}
private:
void balanceHeaps() {
if (maxHeap.size() > minHeap.size() +1) {
// 如果 maxHeap 中的数字总数大于 minHeap 中的数字总数加一,则将 maxHeap 的堆顶数字加入 minHeap int num = maxHeap.top();
maxHeap.pop();
minHeap.push(num);
} else if (maxHeap.size() +1 < minHeap.size()) {
// 如果 minHeap 中的数字总数大于 maxHeap 中的数字总数加一,则将 minHeap 的堆顶数字加入 maxHeap int num = minHeap.top();
minHeap.pop();
maxHeap.push(num);
}
}
};
**示例用法**
cppint main() {
MedianFinder medianFinder;
// 添加数字到数据流中 medianFinder.addNum(1);
medianFinder.addNum(2);
medianFinder.addNum(3);
// 查找当前数据流中的中位数 double median = medianFinder.findMedian();
std::cout << "Current median: " << median << std::endl;
return0;
}
**注释**
* `addNum(int num)` 方法用于将数字添加到数据流中。
* `findMedian()` 方法用于查找当前数据流中的中位数。
* `balanceHeaps()` 方法用于重新调整 maxHeap 和 minHeap,以确保它们中数字的总数相等。
这个实现使用两个堆来存储当前数据流中的数字,一个大顶堆和一个小顶堆。这样可以实时计算出当前数据流中的中位数,并且空间复杂度为 O(n),其中 n 是当前数据流中的数字总数。

