原文地址: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編程語言