【剑指offer】面试题30:最小的 k 个数

题目:

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

思路:

这个是O(nlogk)时间复杂度的思路:用一个容器来保存最先的k个数,这样每次来一个数时,用这个数和容器中k个数中的最大值进行比较;如果比最大值大,则舍弃;比最大值小,则删除最大值,并将该值加入容器。那么问题就是应该选用什么样的容器?

容器需要做3件事:一是在k个数中找最大值,二是删除最大值,三是插入新数。如果用二叉树来实现这个容器,则可以在O(logk)的时间内实现这三个步骤。可以选用红黑树,STL中的set和multiset都是基于红黑树实现。

注意:

考虑无效输入时,也要记得考虑k;

multiset的插入是insert操作,删除是erase操作,遍历和取值是迭代器、没有下标操作符[]。

class Solution {
public:
    vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
        vector<int>  res;
        if(k<1 || input.size()<k)  return res;
        
        multiset<int,greater<int> > leastNumbers;
        for(int i=0;i<input.size();++i)
        {
            if(leastNumbers.size()<k)
            {
                leastNumbers.insert(input[i]);
            }
            else if(input[i]<*leastNumbers.begin())
            {
                leastNumbers.erase(leastNumbers.begin());
                leastNumbers.insert(input[i]);
            }
        }
        
        for(multiset<int,greater<int> >::iterator iter=leastNumbers.begin();iter!=leastNumbers.end();
              ++iter)
        {
            res.push_back(*iter);
        }//可以新建一个vector,用vector的构造函数 vector<int>  res2(leastNumbers.begin(),leastNumbers.end());
        
        return res;
    }
};
原文地址:https://www.cnblogs.com/buxizhizhou/p/4722302.html