正文
【面试题030】最小的k个数
小程序:扫一扫查出行
【扫一扫了解最新限行尾号】
复制小程序
【扫一扫了解最新限行尾号】
复制小程序
【面试题030】最小的k个数
题目:
输入n个整数,找出其中最小的k个数。
例如输入4、5、1、6、2、7、3、8这8个字,则其中最小的4个数字是1、2、3、4。
思路一:
可以同样的基于随机快速排序的Partition函数,来对数组做划分,
基于k来作调整,返回调用Partition函数,直到左边的k个数字是整个数组中最小的k个数字。
ps.这种方法要修改数组中数字的顺序,因为Partition函数会调整数组中数字的顺序。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | #include <iostream> using namespace std; void Swap(int *a, int *b) int Partition(int *numbers, int beg, int end) void GetLeastNumbers(int *input, int n, int *output, int k) } int main() |
思路二:
首先创建一个大小为k的容器来存储最小的k个数字,
遍历这n个数字,如果容器大小小于k,就放入。如果容器已经满了,则跟容器中的最大数字做比较,
如果大于最大数字,遍历下一个,如果小于当前已有的最大值,替换当前这个最大值。
如果用二叉树来实现这个容器,那么我们能在O(logk)
——我想到了最大堆,在O(1)时间内获得已有的k个数字中的最大值,但是需要O(logk)时间完成删除及插入操作。
我们可以利用红黑树来实现我们的容器,STL中set和multiset都是基于红黑树实现的。
C++ Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | #include <iostream> #include <set> #include <vector> using namespace std; typedef multiset<int, greater<int> > intSet; void GetLeastNumbers(const vector<int> &data, intSet &leastNumbers, int k) vector<int>::const_iterator iter = data.begin(); if (*iter < * (leastNumbers.begin())) int main() while(!leastNumbers.empty()) cout << endl; |