标签:
1.题目描述
翻译过来就是对输入的数字找出其中位数。
2.解题思路
一开始,我想着这是动态输入,所以必须放弃数组这些静态的数据结构。首先想到了平衡二叉树,然而太麻烦了。后面又想到了大顶堆以及小顶堆,但是不知如何运用,就上这道题discuss瞅了瞅。结果发现了一种double heap解法,十分带感,总体思路就是比中位数大的数字放一边(大数堆),小的放另一边(小数堆)。然后也接触了并且运用一种新的队列用法——优先队列。插入数字过程中,始终保持大数堆大小大于等于小数堆,以便最后输出中位数。代码如下:
class MedianFinder { private: priority_queue<int, vector<int>,greater<int>>Greater;//小数字一半,顶部为其中最大的 priority_queue<int, vector<int>, less<int>>Less;//大数字一半,顶部为其中最小的 int length; public: MedianFinder(){ length = 0; } // Adds a number into the data structure. void addNum(int num) { if(length == 0){ Greater.push(num); length++; return; } if(length % 2 == 0){//如果大堆和小堆一样大,保证小数字堆大小始终小于等于大数字堆大小(方便输出中位数Greater.top()) if(num >= Less.top()){//比小数字堆最大数大,插入大数字堆 Greater.push(num); } else{//否则调整 Greater.push(Less.top()); Less.pop(); Less.push(num); } } else{ if(Less.size() == 0){//小数字堆为空 if(num >= Greater.top()){//把输入数字给大数字堆,大数字堆原来数据给小数字堆 Less.push(Greater.top()); Greater.pop(); Greater.push(num); } else{//直接插小数字堆 Less.push(num); } length++; return; } if(num >= Greater.top()){//大数堆比小数堆多一个,而且比大数堆最小数大,把大堆最小插入小堆,再把num插入大堆 Less.push(Greater.top()); Greater.pop(); Greater.push(num); } else{//直接插小堆 Less.push(num); } } length++; } // Returns the median of current data stream double findMedian() { if(length % 2 == 0){ float mid = (Greater.top() + Less.top())/2.0; return mid; } else{ return Greater.top();//大堆中最小的为中位数 } } };
3.收获
对堆的应用有了新了理解,而且学会了优先队列这种很有用的数据结构
LeetCode之Find Median from Data Stream
标签:
原文地址:http://www.cnblogs.com/gzc-676/p/5077031.html