输入n个整数,找出其中最小的k个数。例如,输入4、5、1、6、2、7、3、8这8个数字,则最小的4个数字是1、2、3、4。
思路:O(nlogn)排序,然后输出。额,肯定速度上还有更高的要求。跟求中位数一样花O(n)的时间一样,这个等于求第k小的进行左小右大操作。那么代码如下:
void GetLeastNumbers(int* input,int n,int* output,int k)
{
if(input==nullptr||output==nullptr||k>n||n<=0||k<=0)
return;
int start=0;
int end=n-1;
int index=Partition(input,n,start,end);
while(index!=k-1)
{
if(index>k-1)
{
end=index-1;
index=Partition(input,n,start,end);
}
else
{
start=index+1;
index=Partition(input,n,start,end);
}
}
for(int i=0;i<k;i++)
output[i]=input[i];
}
既然是基于快排思想的,那么对输入数组就有修改,那么还有一种O(nlogk)的不改变输入数组的方法。思路也很简单,来一个大小为k的容器存储最小的k个数字,一波遍历,如果容器未满,直接添加,如果容器满了,那么就替换容器中的最大值。那么对容器而言,我们需要它每次得到最大值,那么大顶堆可以考虑。作者更是给出了红黑树,那么我。。。却忘了红黑树的定义。代码就不给出了,相较之下我更倾向于快排思路。