题解 | #售价的中位数#

售价的中位数

https://www.nowcoder.com/practice/a1c7e3a0b2fa46da8a3430617b7d74ca

考察的知识点:优先队列、对顶堆

题目分析:

因为序列可能是无序的,每加入一个数就需要对所有数进行排序。如果我们将排好序的序列一分为二,发现中位数只与左边序列的最大值和右边序列的最小值有关。可以通过使用对顶堆找到这个最大值和最小值,即使用大顶堆保存左边较小的序列,可以直接获得这些序列中的最大值;使用小顶堆保存右边较大的序列,可以直接获得这些序列中的最小值。

构造这两个堆需要注意两点:

  1. 为了让更大的数放在上面的堆上,如果新加入的价格大于中位数,则将该价格放入上面的小顶堆中;反之放入下面的大顶堆中。
  2. 为了让大顶堆中容纳数的范围是从1~N / 2 (注意向0取整),小顶堆中容纳数的范围是(N + 1) / 2 ~ N,当各个堆中的元素数量小于理应存放的个数时,将另一个堆中的数转移到这个堆中即可。

最后,因为中位数是第(N + 1) / 2个数,所以当元素个数总共为奇数个时,返回小顶堆的堆顶;否则返回两个堆中堆顶的和除以2。

所用编程语言:C++

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param prices int整型vector 
     * @return double浮点型vector
     */
    vector<double> findMedianPrice(vector<int>& prices) {
        // write code here
        priority_queue<int, vector<int>, greater<int>> gheap;
        priority_queue<int, vector<int>, less<int>> lheap;
        vector<double> res;
        int mid = 0;
        int k = 0;
        for (auto &price: prices) {
            if (price > mid) gheap.push(price);
            else lheap.push(price);
            k++;
            if  (gheap.size() < (k + 1) / 2) {
                gheap.push(lheap.top());
                lheap.pop();
            }
            if (lheap.size() < k / 2) {
                lheap.push(gheap.top());
                gheap.pop();
            }
            if (k % 2) res.push_back(gheap.top());
            else {
                res.push_back(((double)gheap.top() + lheap.top()) / 2);
            }
            mid = gheap.top();
        }
        return res;
    }
};

全部评论

相关推荐

好久没来牛客了,今天面试了一个实习生,感觉对方形象乱糟糟的,头发像鸡窝,像刚睡醒就来面试了,第一印象直接大打折扣,感觉我没有受到应有的尊重,再加上对方业务能力也一般,我直接挂掉;大家面试的时候还是好好收拾一下自己吧,争取给面试官留下个好印象,面试这东西还是存在眼缘的
MinJerous:更在乎本质,应该看候选人是否和岗位需要的能力匹配。洗脸/不洗头都无所谓吧,说不定人家刚刚通宵准备,就是为了这场面试呢?你挂掉他核心原因还是他能力不行,而不是形象。就算形象好点,能力不行你敢给过吗,不怕后面+1质疑你
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务