`
xitonga
  • 浏览: 589710 次
文章分类
社区版块
存档分类
最新评论

最小的k个数字

 
阅读更多
/*****************************************************************
题目:输入n个整数,找出其中最小的k个数。例如输入4,5,1,6,2,7,3,8这
8个数字,则最小的4个数字是1,2,3,4。
*****************************************************************/
#include<iostream>
#include<set>
#include<vector>

using namespace std;

void swap(int* pNum1, int* pNum2)
{
	int nTemp = *pNum1;
	*pNum1 = *pNum2;
	*pNum2 = nTemp;
}

int partition(int* numbers, int start, int end)
{
	if(numbers == NULL || start>end)
		throw new std::exception("invalid input!\n");

	int standard = numbers[end];
	int small = start-1;

	for(int i=start; i<end; ++i)
	{
		if(numbers[i] < numbers[end])
		{
			++small;
			if(i != small)
			swap(&numbers[i],&numbers[small]);
		}
	}

	++small;
	swap(&numbers[small], &numbers[end]);
	return small;
}
//方法1
//按照第29题的思路,可以给予partition来解决这个问题
//如果基于数组的第k个数字来调整,使得第比第k个数字小的所有
//数字都位于数组的左边,比第k个数字大的所有数字都位于数组的
//右边。这样调整后,位于数组中左边的k个数字就是最小的k个数
//时间复杂度为O(N)
void GetLeastNumbers(int* input,int n, int* output, int k)
{
	if(input == NULL || n<=0 || output == NULL || k<=0 || k>n)
		throw std::exception("invalid question!");

	int start = 0;
	int end = n-1;

	int index = partition(input,start,end);
	while(index!=k-1)
	{
		if(index>k-1)
		{
			end = index-1;
			index = partition(input,start,end);
		}
		else
		{
			start = index + 1;
			index = partition(input, start, end);
		}
	}
	for(int i=0; i<k; ++i)
	{
		output[i] = input[i];
	}
}

//方法2:特别适合处理海量数据
//用堆或者红黑树实现。先填满容器k个元素,后面的数字如果大于容器中最大值,、
//就将容器中最大值删除,加入新元素。
//这里采用multiset解决问题,它是由红黑树实现的
typedef multiset<int,greater<int>> intSet;
typedef multiset<int,greater<int>>::iterator setIterator;

void GetLeastNumbers(const vector<int>& data, intSet& leastNumbers,
					 int k)
{
	leastNumbers.clear();

	if(k<1 || data.size()<k)	//输入无效
		return;

	vector<int>::const_iterator iter = data.begin();
	for(;iter != data.end(); ++iter)
	{
		if((leastNumbers.size())<k)
			leastNumbers.insert(*iter);
		else
		{
			setIterator iterGreatest = leastNumber.begin();

			if(*iter < *(leastNumbers.begin()))
			{
				leastNumbers.erase(iterGreatest);
				leastNumbers.inset(*iter);
			}
		}
	}
}

void test()
{
	const int length = 8;
	int input[length] = {4,5,1,6,2,7,3,8};
	const int k = 4;
	int output[k];
	GetLeastNumbers(NULL,0,output,k);
	for(int i=0; i<k; ++i)
	{
		printf("%d\t",output[i]);
	}
}
int main()
{
	try{
	test();
	}
	catch(std::exception ex)
	{
		std::cerr<<ex.what();
	}
	return 0;
}
第一种方法复杂度第,但要改变输入的数据;而第二种方法不会改变输入的数据适用于n很大,k较小的问题

==参考剑指offer

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics