cherrychenlee

导航

 

原文地址:https://www.jianshu.com/p/cb3d31082bec

时间限制:1秒 空间限制:32768K

题目描述

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

我的代码

class Solution {
public:
    /*在非海量数据的情况下,Top-K问题的首推解法就是快排中的Partition算法。
    不仅平均时间复杂度优越,可以达到O(n),并且相比于基于堆的算法
    (包括:min_heapify、build_heap、insert等一系列过程),编码更简洁。
    在海量数据的情况下,还是老老实实选择基于堆的这一数据结构的算法吧。
    时间复杂度为O(nlogk)。并且大多数高级编程语言中都应该内置了基于堆的API,
    所以编写起来也没有那么麻烦。
    基于Partition算法:
    选择一个Position(称为基准),基于该算法的Top-K算法,非常受Position好坏的影响,
    所谓的坏,有可能使时间复杂度达到O(n*n)。
    然后利用Partition算法进行划分,如果Partition得到的p小于K,则继续划分p的右边;
    如果p大于K,则继续划分p的左边;如果p等于K,则算法结束。
    这种算法的缺点是需要针对数据做频繁的移动操作,
    如果数据量较大就需要使用文件的形式进行分治计算。*/
    void swap(int& a,int& b){
        int tmp=a;
        a=b;
        b=tmp;
    }
    int Partition(vector<int> &input, int s,int e, int k){
        int base=input[s];
        int i=s+1,j=e;
        while(i<j){
            while((i<=e)&&(input[i]<=base))
                i++;
            while((j>=0)&&(input[j]>=base))
                j--;
            if(i<j)
                swap(input[i],input[j]);
        }
        swap(input[s],input[j]);
        return j;
    }
    int GetKID(vector<int> &input, int s,int e, int k){
        int p=Partition(input,s,e,k);
        int num=p-s+1;
        int id=-1;
        if(num==k)
            id=p;
        else if(num>k)
            id=GetKID(input,s,p-1,k);
        else
            id=GetKID(input,p+1,e,k-num);
        return id;
    }
    vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
        vector<int> res;
        int n=input.size();
        if(n<1 || k<1 || n<k)
            return res;
        int id=GetKID(input,0,n-1,k);
        for(int i=0;i<=id;i++)
            res.push_back(input[i]);
        return res;
    }
};

运行时间:3ms
占用内存:472k

class Solution {
public:
    vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
        vector<int> res;
        int n=input.size();
        if(n<1 || k<1 || n<k)
            return res;
        multiset<int,greater<int>> m;
        multiset<int,greater<int>>::iterator itG;
        multiset<int,greater<int>>::reverse_iterator ritG;
        for(int i=0;i<n;i++){
            if(m.size()<k)
                m.insert(input[i]);
            else{
                itG=m.begin();
                if(input[i]<*itG){
                m.erase(itG);
                m.insert(input[i]);
                }
            }
        }
        for(ritG=m.rbegin();ritG!=m.rend();ritG++)
            res.push_back(*ritG);
        return res;
    }
};

运行时间:3ms
占用内存:476k

posted on 2019-05-06 21:29  cherrychenlee  阅读(90)  评论(0编辑  收藏  举报