题目描述
输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,
解法1:基于Partition函数的时间复杂度为O(n)的解法,只有当我们可以修改原始数组时可用
1 class Solution { 2 public: 3 int Partition(vector<int> &input, int begin, int end) 4 { 5 int tmp=input[begin]; 6 while(begin<end) 7 { 8 while(begin<end && input[end]>=tmp)--end; 9 input[begin]=input[end]; 10 while(begin<end && input[begin]<=tmp)++begin; 11 input[end]=input[begin]; 12 } 13 input[begin]=tmp; 14 return begin; 15 } 16 vector<int> GetLeastNumbers_Solution(vector<int> input, int k) { 17 int length=input.size(); 18 vector<int> res; 19 if(length==0 || k>length || k<=0)return res; 20 int begin=0; 21 int end=length-1; 22 while(true) 23 { 24 int mid=Partition(input, begin, end); 25 if(mid==k)break; 26 if(mid>k)end=mid-1; 27 else begin=mid+1; 28 } 29 for(int idx=0; idx<k; ++idx) 30 { 31 res.push_back(input[idx]); 32 } 33 return res; 34 } 35 };
解法2:时间复杂度为O(nlogk)的算法。遍历数组,用multiset来存放最小的k个数
1 class Solution { 2 public: 3 vector<int> GetLeastNumbers_Solution(vector<int> input, int k) { 4 int length=input.size(); 5 vector<int> res; 6 if(length==0 || k<=0 || k>length)return res; 7 std::multiset<int, std::greater<int>> minSet; 8 for(int idx=0; idx<length; ++idx) 9 { 10 if(minSet.size()<k)minSet.insert(input[idx]); 11 else{ 12 std::multiset<int>::iterator it=minSet.begin(); 13 if(*it>input[idx]) 14 { 15 minSet.erase(it); 16 minSet.insert(input[idx]); 17 } 18 } 19 } 20 for(auto it=minSet.begin(); it!=minSet.end(); ++it) 21 { 22 res.push_back(*it); 23 } 24 return res; 25 } 26 };