最小的k个数

  一、问题描述

输入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》

    

    

你可能感兴趣的:(最小的k个数快速排序堆排序)