最小的K個數

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

時間限制:1秒 空間限制:32768K編程

題目描述

輸入n個整數,找出其中最小的K個數。例如輸入4,5,1,6,2,7,3,8這8個數字,則最小的4個數字是1,2,3,4,。api

個人代碼

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編程語言

相關文章
相關標籤/搜索