题目:输入n个整数,找出其中最小的k个数。例如输入4,5,1,6,2,7,3,8.则最小的4个数字是1、2、 3、 4.
思路:这道题有很多解法,最简单的思路为将n个数排序,然后输出排序后的k个数。还有就是利用堆的特点来解决,但都是排序的一种变体,时间复杂度为O(nlogn).这里我们用另外一种解法-分治法,基于快速排序的partition函数得来,如果基于数组的第k个数字来调整,使得比第k个数字小的所有数字都位于数组的左边,比第k个数字大的所有数字都位于数组的右边,这样调整之后,位于数组中左边的k个数字就是最小的k个数字。
代码:
#include <iostream>
#include <vector>
using namespace std;
int partition(vector<int> &vec,int beg, int end){
if(beg < end){
int key = vec[beg];
int low = beg, high = end;
while(low < high){
while(low < high && key < vec[high])
--high;
vec[low] = vec[high];
while(low < high && key > vec[low])
++low;
vec[high] = vec[low];
}
vec[low] = key;
return low;
}
return -1;
}
void findmink(vector<int> &vec, int k){
int beg = 0, end = vec.size()-1, position = partition(vec, beg, end);
while(position != k-1){
if(position > k-1){
end = position - 1;
position = partition(vec,beg, end);
}else{
beg = position+1;
position = partition(vec, beg, end);
}
}
for(int i=0;i<=position;++i)
cout << vec[i] << " ";
cout << endl;
}
int main(){
int a[] = {4,5,1,6,2,7,3,8};
vector<int> vec(a,a+8);
findmink(vec, 4);
return 0;
}