C++每日一练13.最小的k个数

Posted 鱼酱2333

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++每日一练13.最小的k个数相关的知识,希望对你有一定的参考价值。

描述
给定一个长度为 n 的可能有重复值的数组,找出其中不去重的最小的 k 个数。例如数组元素是4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4(任意顺序皆可)。

数据范围:0<= k,n≤10000,数组中每个数的大小010000≤val≤1000
要求:空间复杂度 O(n)O(n) ,时间复杂度 O(nlogn)O(nlogn)

方法一:排序

直接排序,然后去前k小数据。

class Solution 
public:
    vector<int> GetLeastNumbers_Solution(vector<int> input, int k) 
        vector<int> ret;
        if (k==0 || k>input.size()) return ret;
        sort(input.begin(), input.end());
        return vector<int>(input.begin(), input.begin()+k);  
    
;

时间复杂度:O(n long n)
空间复杂度:O(1)

方法二:堆排序

建立一个容量为k的大根堆的优先队列。遍历一遍元素,如果队列大小<k,就直接入队,否则,让当前元素与队顶元素相比,如果队顶元素大,则出队,将当前元素入队

class Solution 
public:
    vector<int> GetLeastNumbers_Solution(vector<int> input, int k) 
        vector<int> ret;
        if (k==0 || k > input.size()) return ret;
        priority_queue<int, vector<int>> pq;
        for (const int val : input) 
            if (pq.size() < k) 
                pq.push(val);
            
            else 
                if (val < pq.top()) 
                    pq.pop();
                    pq.push(val);
                
 
            
        
 
        while (!pq.empty()) 
            ret.push_back(pq.top());
            pq.pop();
        
        return ret;
    
;

时间复杂度:O(nlongk), 插入容量为k的大根堆时间复杂度为O(longk), 一共遍历n个元素
空间复杂度:O(k)

以上是关于C++每日一练13.最小的k个数的主要内容,如果未能解决你的问题,请参考以下文章

C/C++每日一练(20230401)

「 每日一练,快乐水题 」908. 最小差值 I

蓝桥杯C/C++每日一练之数列特征

「 每日一练,快乐水题 」剑指 Offer 15. 二进制中1的个数

「 每日一练,快乐水题 」908. 最小差值 I

C语言每日一练——第69天:求最小公倍数