/***************************************************************** 题目:输入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
原文:http://blog.csdn.net/walkerkalr/article/details/21253711