面试题30:最小的k个数

来源:互联网 发布:mac 相对于卷宗的格式 编辑:程序博客网 时间:2024/06/03 07:53
1.输入n个整数,找出其中的最小的k个数,例如输入4,5,1,6,2,7,3,8 这8个数字,则其中最小的4个数字是1,2,3,4,。
分析:
方法一,可以采用类似快速排序的解法,基于数组中第k个数来进行调整,使得比第k个数字大的所有数字都在数组的右边,小的都在第k个数字的左边。

方法二:可以创建一个大小为k的容器来存储最小的k个数,如果容器中的书少于k个,则直接把读入的整数放入容器中,如果容器满了,此时得找出这k个数中的最大值,再拿这次待插入的值和最大值进行比较,如果比它大,则不进行插入,如果比它小,则替换k个数中的最大值,直到数组中的所有数访问完,则最后容器中的数就是k个最小的数。应为当容器满的时候,每次得计算容器中的最大值,为了在短时间内计算出最大值,可以采用类似红黑树的结构,假设k个节点,则可以在lg(k)的时间内找出最大值。


源码:

/*** 功能说明:Description* 作者:K0713* 日期:2016-7-22**/#include<iostream>#include<vector>#include<set>using namespace std;typedef multiset<int, greater<int> >            intSet;typedef multiset<int, greater<int> >::iterator  setIterator;//产生随机数int RandomInRange(int min, int max);//交换两个数值void Swap(int* num1, int* num2);//基于快速排序的划分int Partition(int data[], int length, int start, int end);//基于快速排序的解法void GetLeastNumbers_Solution1(int* input, int n, int* output, int k);//基于替换的解法void GetLeastNumbers_Solution2(const vector<int>& data, intSet& leastNumbers, int k);int main(){int data[] = {4, 5, 1, 6, 2, 7, 3, 8};vector<int> vectorData;for(int i = 0; i < 8; ++ i)vectorData.push_back(data[i]);int k=4;int* output = new int[k];cout<<"solution 1: "<<endl;GetLeastNumbers_Solution1(data, 8, output, k);for(int i = 0; i < k; ++ i)cout<<output[i]<<" ";cout<<endl;cout<<"solution 2: "<<endl;intSet leastNumbers;GetLeastNumbers_Solution2(vectorData, leastNumbers, k);for(setIterator iter = leastNumbers.begin(); iter != leastNumbers.end(); ++iter)cout<< *iter<<" ";cout<<endl;system("PAUSE");return 0;}int Partition(int data[], int length, int start, int end){if (data == NULL || length <= 0 || start < 0 || end >= length)throw new std::exception("Invalid Parameters");int index = RandomInRange(start, end);Swap(&data[index], &data[end]);int small = start - 1;for (index = start; index < end; ++index){if (data[index] < data[end]){++small;if (small != index)Swap(&data[index], &data[small]);}}++small;Swap(&data[small], &data[end]);return small;}int RandomInRange(int min, int max){int random = rand() % (max - min + 1) + min;return random;}void Swap(int* num1, int* num2){int temp = *num1;*num1 = *num2;*num2 = temp;}void GetLeastNumbers_Solution1(int* input, int n, int* output, int k){if(input == NULL || output == NULL || 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];}void GetLeastNumbers_Solution2(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 = leastNumbers.begin();if(*iter < *(leastNumbers.begin())){leastNumbers.erase(iterGreatest);leastNumbers.insert(*iter);}}}}


0 0
原创粉丝点击