当前位置:实例文章 » 其他实例» [文章]剑指offer(C++)-JZ41:数据流中的中位数(算法-排序)

剑指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 是当前数据流中的数字总数。

其他信息

其他资源

Top