您的位置:首页 > 其它

最小的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,编码:

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。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: