最小的k个数
2016-04-03 16:43
211 查看
1,问题:
输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。
2,想法:
(1),直接排序,然后选取前k个最小的数,时间o(nlogn)
(2),采用冒泡排序的思想,最外层for循环为k,时间复杂度为O(kn)
(3),采用快速排序中Partition的方法,找到第k大数字的位置,然后输出前k个数字。时间o(n)
但是这三种方法都要改变原数组的内容,且如果数据量过大而不能一次性存放在内存时就不合适了。
(4),利用STL中的容器set和multiset,它们都是基于红黑树实现的,能够在logn的时间内实现查找,插入和删除,自动以升序排序。
若以我们只需要在内存中维持一个大小为k的set容器,以降序排列。那么当前容器的最大值肯定在begin()上,再从原数组中取一个数,若大于当前set的最大值就放弃,若小于则替换。扫描一遍即可。时间复杂度为o(nlogk)。
3,编码:
输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。
2,想法:
(1),直接排序,然后选取前k个最小的数,时间o(nlogn)
(2),采用冒泡排序的思想,最外层for循环为k,时间复杂度为O(kn)
(3),采用快速排序中Partition的方法,找到第k大数字的位置,然后输出前k个数字。时间o(n)
但是这三种方法都要改变原数组的内容,且如果数据量过大而不能一次性存放在内存时就不合适了。
(4),利用STL中的容器set和multiset,它们都是基于红黑树实现的,能够在logn的时间内实现查找,插入和删除,自动以升序排序。
若以我们只需要在内存中维持一个大小为k的set容器,以降序排列。那么当前容器的最大值肯定在begin()上,再从原数组中取一个数,若大于当前set的最大值就放弃,若小于则替换。扫描一遍即可。时间复杂度为o(nlogk)。
3,编码:
class Solution { public: //下边是利用partition的思想 /*int Partition(vector<int> &input, int length, int start, int end) { int pivot = input[start];//枢轴 int i = start; int j = end; while (i < j) { //找到第一个比pivot小的数 while (i < j && input[j] >= pivot)j--; //交换 if (i < j)input[i] = input[j]; //找到第一个比pivot大的数 i = i + 1; while (i < j && input[i] <= pivot)i++; if (i < j)input[j] = input[i]; j = j - 1; } input[i] = pivot; return i; } vector<int> GetLeastNumbers_Solution(vector<int> input, int k) { vector<int> vec; if (input.empty() || k ==0 || k > input.size()) { return vec; } if (k == input.size()) { return input; } //找到第k大的数字 int length = input.size(); int start = 0; int end = length - 1; int index = Partition(input, length, start, end); while (index != k - 1) { if (index > k - 1) { end = index - 1; Partition(input, length, start, end); } else { start = index + 1; Partition(input, length, start, end); } } for (int i = 0; i <= index; i++) { vec.push_back(input[i]); } return vec; } */ typedef multiset<int, greater<int>> intset;//把multiset的默认升序变为降序排列 typedef multiset<int, greater<int>>::iterator setiterator; vector<int> GetLeastNumbers_Solution(vector<int> input, int k) { //这里是利用排序的思想 /*vector<int> vec; if (input.size() == 0 || k == 0 || k > input.size()) { return vec; } //sort(input.begin(), input.end()); //partial_sort(input.begin(), input.begin() + k, input.end()); nth_element(input.begin(), input.begin() + k - 1, input.end()); for (int i = 0; i < k; i++) { vec.push_back(input[i]); } return vec; */ //这里是利用红黑树实现的容器set来实现n很大k很小的情况 vector<int> vec; intset leastnumber; if (input.size() == 0 || k == 0 || k > input.size()) { return vec; } for (int i = 0; i < input.size(); i++) { if (leastnumber.size() < k) { leastnumber.insert(input[i]); } else { setiterator itergreatest = leastnumber.begin(); if (input[i] < *leastnumber.begin()) { leastnumber.erase(itergreatest); leastnumber.insert(input[i]); } } } setiterator it = leastnumber.begin(); for (; it != leastnumber.end(); it++) { vec.push_back(*it); } return vec; } };学习一下怎么使用容器set和multiset。
相关文章推荐
- iOS性能优化:Instruments使用实战
- 利用NSCache提升效率
- HDU1695 GCD (欧拉函数+容斥原理)
- Java回调机制解析
- Maven+Spring+SpringMVC+MyBatis框架的搭建(二)
- java 学习心得
- Sublime Text常用快捷键总结附上gif图 更加清晰
- linux下如何检测程序是否运行并重启
- NSoperation和GCD的使用场景
- VJ【背包】
- Fiddler 使用教程
- LightOJ 1138 - Trailing Zeroes (III) (求末尾0为x的最小N---二分)
- hdoj 小兔的棋盘 2067 (DP)
- 集合框架中LinkedList实现类代码分析
- 简单的sql操作
- poj 2386 lake counting
- MyEclipse build path no actions available
- hibernate关系映射,一对多,多对多,以及session方法简介
- SpringMvc的数据校验
- 进程和线程