0
点赞
收藏
分享

微信扫一扫

剑指Offer刷题记录_Day17

倚然君 2022-02-09 阅读 49

排序(中级)

Q1 最小的k个数

感觉比较快的两个思路:

  • 快速排序: 已知快排每一次调用Partition函数会将数列划分为大于小于基准数的两个序列,则我们可以在快排某次调用Partition函数时判断是否是K+1的位置,若是则停止,此时前k个为最小k个数
  • 推排序,小根堆,每次取top,然后与堆底交换,调整。但是手撕堆排序最好从a[1]开始存数,因为此时2 * i 和 2 * i + 1(不越界)正好为孩子节点
class Solution {
public:
    vector<int> getLeastNumbers(vector<int>& arr, int k) {
        
        vector<int> array;
        int len = arr.size();
        priority_queue<int,vector<int>,greater<int> >q;
        for(int i=0;i<len;i++) q.push(arr[i]);
        for(int i=0;i<k;i++)
        {
            array.push_back(q.top());
            q.pop();
        }
        return array;

    }
};

Q2 数据流中的中位数

如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。

class MedianFinder {
public:
    // 最大堆,存储左边一半的数据,堆顶为最大值
    priority_queue<int, vector<int>, less<int>> maxHeap;
    // 最小堆, 存储右边一半的数据,堆顶为最小值
    priority_queue<int, vector<int>, greater<int>> minHeap;

    MedianFinder() {
    }

    // 维持堆数据平衡,并保证左边堆的最大值小于或等于右边堆的最小值
    void addNum(int num) {

        if (maxHeap.size() == minHeap.size()) {
            minHeap.push(num);
            int top = minHeap.top();
            minHeap.pop();
            maxHeap.push(top);
        } else {
            maxHeap.push(num);
            int top = maxHeap.top();
            maxHeap.pop();
            minHeap.push(top);
        }
    }
    
    double findMedian() {
        if (maxHeap.size() == minHeap.size()) {
            return (maxHeap.top()+minHeap.top())/2.0;
        } else {
            return maxHeap.top()*1.0;
        }
    }
};
举报

相关推荐

0 条评论