面试题30——最小的k个数

题目描述

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


解题思路

思路1:按递增排序,然后输出前k个数,简单粗暴,时间复杂度O(nlogn)

思路2:利用partition算法,找到第K大数,输出其左边K个数,时间复杂度O(n)

思路3:开一个规模为K的数组,遍历原数组,若辅助数组未存满K个数,那么直接将遍历到的数放入K数组中;若已经存满K个数,那么,拿当前遍历到的数 与 K数组中最大数进行比较,若当前数小于K中最大数,则将两者进行替换。否则,丢弃当前数,继续遍历,直到遍历完原数组。时间复杂度O(nlogK)


其中,对于K数组需要执行的操作是:1、找最大数;2、删除最大数;3、插入新数。

这三步可以用二叉树来实现,则时间复杂度O(logK)。

用STL的multiset来实现。还可以用大顶堆实现,但比较麻烦。

思路2的实现,参照前一篇博客:http://blog.csdn.net/tommyzht/article/details/47121997

实现代码:


class Solution {
public:
    typedef multiset<int, greater<int>> inset;
    typedef multiset<int, greater<int>>::iterator setIterator;
    vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
        inset leastKnum;
        leastKnum.clear();
        
        vector<int> ans;
        if(k<1 || input.size()<k)
            return ans;
        vector<int>::const_iterator iter = input.begin();
        
        for(;iter != input.end(); iter++)
        {
        	if((leastKnum.size()) < k)
                leastKnum.insert(*iter);
            else
            {
                setIterator iterGrest = leastKnum.begin();
                if(*iter < *(leastKnum.begin()))
                {
                        leastKnum.erase(iterGrest);
                        leastKnum.insert(*iter);
                }
                
            }
           
        }
        
        for(auto a : leastKnum)
            ans.push_back(a);
        
        return ans;
    }
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值