码迷,mamicode.com
首页 > 其他好文 > 详细

最小的k个数

时间:2014-12-04 16:00:45      阅读:174      评论:0      收藏:0      [点我收藏+]

标签:数组   最小的k个数   

题目:输入n个整数,找出其中最小的k个数字。例如输入4,5,1,6,2,4,7,3这8个数字,则最小的4个数字是1,2,3,4.

分析:最简单办法,将n个数排序,然后最前面的k个就是最小的k个数字。这种算法时间复杂度为O(nlogn),还可以进一步提升。

方法一:类似与“数组中出现次数超过一半的数字”中的思想,时间复杂度为O(n),代码如下:

void GetLeastNumbers(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];
}

同样的,这种方法有限制,就是要改动数组。如果不能改动数组,则可以用下面这种方法。

方法二:创建一个大小为k的数据容器来存储最小的k个数字,接下来我们每次输入n个整数中的一个数,如果容器没有满,则直接放入,如果满了,则找出k个数中的最大数,然后和这个数比较大小,如果比最大数大,则直接抛弃这个数,如果较小,则替换最大数。时间复杂度为O(nlogk),特别适合处理海量数据。实现如下:

typedef multiset<int,greater<int>> intSet;
typedef multiset<int,greater<int>>::iterator setIteeator;
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=leastNumbers.begin();
            
            if(*iter<*(leastNumbers.begin()))
            {    
                leastNumbers.erase(iterGreatest);
                leastNumbers.insert(*iter);
            }
        }
    }
}


本文出自 “仙路千叠惊尘梦” 博客,请务必保留此出处http://secondscript.blog.51cto.com/9370042/1586198

最小的k个数

标签:数组   最小的k个数   

原文地址:http://secondscript.blog.51cto.com/9370042/1586198

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!