一、问题描述
输入n个整数,找出其中最小的k个数。例如输入4、5、1、6、10、8、12、20这8个数,则最小的4个数字是1、4、5、6。
二、解题思路
解法1.最简单的思路莫过于把输入的n个整数排序,排序之后位于最前面的k个数就是最小的k个数。时间复杂度O(nlogn)。这个方法我就不在这里复述了。
解法2.利用上一篇博客http://blog.csdn.net/jasonjwl/article/details/50312191,快排的思想,时间复杂度为O (n)
#include <iostream>
#include <string>
#include <cstring>
#include <algorithm>
using namespace std;
int Partition (int arr[],int p,int r)
{
int i = p,j =r+1;
int x = arr[p];
//将小于x的元素交换到左边区域
//将大于x的元素交换到右边区域
while(true){
while(arr[++i]<x&&i<r);
while(arr[--j]>x);
if(i>=j) break;
swap(arr[i],arr[j]);
}
//把枢纽放在正确的位置
arr[p] = arr[j];
arr[j] = x;
return j;
}
void GetLeastNumbers(int* arr,int n,int k)
{
if(arr == NULL || k>n || n<=0 || k<=0)
return ;
int start =0;
int end = n-1;
int index = Partition(arr,start,end);
while(index!=k-1)
{
if(index > k-1)
{
end = index -1;
index = Partition(arr,start,end);
}
else
{
start = index + 1;
index = Partition(arr,start,end);
}
}
for(int i=0;i<k;++i)
cout<<arr[i]<<endl;
}
int main()
{
int arr[] = {4,5,1,6,10,8,12,20};
GetLeastNumbers(arr,8,4);
system("pause");
}
解法3.先创建一个大小为k的数据容器来存储最小的k个数字,接下来我们每次从输入的n个整数中读入一个数。如果容器中已有的数字少于k个,则直接把这次读入的整数放入容器之中;如果容器中已有k个数字了,也就是容器已满,此时我们不能再插入新的数字而只能替换以后的数字。找出这已有的k个数中的最大值,然后拿这次待插入的整数和最大值进行比较。如果待插入的值比当前已有的最大值小,则用这个数替换当前已有的最大值。
感谢:何海涛 《剑指offer》