最小的K个数

作者: cherryleechen | 来源:发表于2019-05-06 21:28 被阅读0次

    时间限制: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

    相关文章

      网友评论

        本文标题:最小的K个数

        本文链接:https://www.haomeiwen.com/subject/ecytoqtx.html