码迷,mamicode.com
首页 > 其他好文 > 详细

LeetCode之Find Median from Data Stream

时间:2015-12-25 22:27:21      阅读:218      评论:0      收藏:0      [点我收藏+]

标签:

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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!