TOP-K 堆实现

2019-08-17  本文已影响0人  我麦

题目描述

输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。

题解

TOP-K问题使用堆实现可以实现最小的时间复杂度O(nlog(k))。方法是先取出数组中的k个数构造大顶堆(最小的K个值),然后逐个读取数组中的剩下的数,并与堆顶比较,如果小于堆顶,则与堆顶元素替换,再调整堆。数组读取完成后,输出堆中的k个元素就是最小的k个数字。

使用STL自己实现堆结构

class Solution {
public:
    void adjust(vector<int> &v, int start, int len){
        int tmp = v[start];
        for(int i = 2*start+1; i < len; i = i*2+1){ // i*2+1为左子节点,i*2+2为右子节点
            if(i != (len-1) && v[i] < v[i+1])  // 如果右节点大于左节点
                i++;
            if(tmp < v[i]){
                v[start] = v[i];
                start = i;
            }else
               break;
        }
        v[start] = tmp;
    }
    void buildHeap(vector<int> &v){
        for(int i = v.size()/2-1; i>=0; i--)  // 从第一个非叶结点开始建堆
            adjust(v, i, v.size());
    }
    vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
        if(input.size()==0)
            return input;
        if(k>input.size() || k <=0){
            vector<int> v;
            return v;
        }
        buildHeap(input);
        for(int i = k; i < input.size(); i++){
            if(input[i] < input[0]){
                int tmp = input[0];
                input[0] = input[i];
                input[i] = tmp;
                adjust(input, 0, k);  //调整大小为k的堆
            }
        }
        vector<int> v(input.begin(), input.begin()+k);
        return v;
    }
};

STL的priority_queue已经使用了大顶堆进行实现,所以可以直接使用priority_queue实现。

class Solution {
public:
    vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
        if(input.size()==0)
            return input;
        if(k>input.size() || k <=0){
            vector<int> v;
            return v;
        }
        priority_queue<int> q;
        for(int i = 0; i < input.size(); i++){
            if(q.size()<k)
                q.push(input[i]);
            else if(input[i] < q.top()){
                q.pop();
                q.push(input[i]);
            }
        }
        vector<int> v;
        while(!q.empty()){
            v.push_back(q.top());
            q.pop();
        }
        return v;
    }
};

若想使用priority_queue来实现查找最大的K个数,则需要使用小顶堆,stl中声明小顶堆的priority_queue的方法如下:

priority_queue<int, vector<int>, greater<int>> q;
上一篇下一篇

猜你喜欢

热点阅读