leetcode 295. Find Median from Data Stream 双优先级队列 + 中位数查找

来源:互联网 发布:kitti数据集格式 编辑:程序博客网 时间:2024/06/05 11:12

Median is the middle value in an ordered integer list. If the size of the list is even, there is no middle value. So the median is the mean of the two middle value.

Examples:
[2,3,4] , the median is 3

[2,3], the median is (2 + 3) / 2 = 2.5

Design a data structure that supports the following two operations:

void addNum(int num) - Add a integer number from the data stream to the data structure.
double findMedian() - Return the median of all elements so far.
For example:

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

用一个最大堆存放比中位数小(或等于)的元素,用一个最小堆存放比中位数大(或等于)的元素。这里关键的方法是insert(),每当要插入一个元素时,根据判断条件将它插入最大堆或是最小堆,并更新最大堆和最小堆,使得最大堆和最小堆中元素的个数之差不超过1,这样中位数就是最大堆或最小堆的堆顶元素。当最大堆和最小堆中元素个数不同(个数相差为1)时,元素个数多的那个堆的堆顶元素即为中位数;如果两者元素个数相同,那么中位数可以是最大堆和最小堆的堆顶元素的值取平均。

建议和这一道题leetcode 480. Sliding Window Median 滑动窗口中位数 一起学习

代码如下:

import java.util.Collections;import java.util.PriorityQueue;/* * 用一个最大堆存放比中位数小(或等于)的元素,用一个最小堆存放比中位数大(或等于)的元素。 * 这里关键的方法是insert(),每当要插入一个元素时,根据判断条件将它插入最大堆或是最小堆, * 并更新最大堆和最小堆,使得最大堆和最小堆中元素的个数之差不超过1,这样中位数就是最大堆 * 或最小堆的堆顶元素。当最大堆和最小堆中元素个数不同(个数相差为1)时, * 元素个数多的那个堆的堆顶元素即为中位数;如果两者元素个数相同,那么中位数可以是最大堆和 * 最小堆的堆顶元素的值取平均 * */class MedianFinder {    private PriorityQueue<Integer> maxHeap;    private PriorityQueue<Integer> minHeap;    public MedianFinder()     {        this.minHeap = new PriorityQueue<Integer>();        this.maxHeap = new PriorityQueue<Integer>(Collections.reverseOrder());    }    // Adds a number into the data structure.    public void addNum(int num)     {        maxHeap.add(num);                      minHeap.add(maxHeap.poll());                     if(maxHeap.size() < minHeap.size())        {            maxHeap.add(minHeap.poll());               }    }    // Returns the median of current data stream    public double findMedian()     {                            if(maxHeap.size() == minHeap.size())            return (maxHeap.peek() + minHeap.peek()) / 2.0;        else            return maxHeap.peek();      }};// Your MedianFinder object will be instantiated and called as such:// MedianFinder mf = new MedianFinder();// mf.addNum(1);// mf.findMedian();

下面是C++的做法,就是维护两个堆来实现中位数的查找

代码如下:

#include <iostream>#include <vector>#include <map>#include <set>#include <queue>#include <stack>#include <string>#include <climits>#include <algorithm>#include <sstream>using namespace std;class MedianFinder {    priority_queue<long> small, large;public:    void addNum(int num)     {        small.push(num);        large.push(-small.top());        small.pop();        if (small.size() < large.size())         {            small.push(-large.top());            large.pop();        }    }    double findMedian()     {        return small.size() > large.size()            ? small.top()            : (small.top() - large.top()) / 2.0;    }};
阅读全文
0 0
原创粉丝点击