ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

剑指 Offer 40. 最小的k个数

2022-05-26 19:03:53  阅读:131  来源: 互联网

标签:arr return Offer int 复杂度 个数 40 vector ans


剑指 Offer 40. 最小的k个数

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

思路

方法一:排序

对原数组从小到大排序后取出前 k 个数即可。时间复杂度为O(nlogn)

方法二:堆

用一个大根堆实时维护数组的前 k 小值。时间复杂度为O(nlogk)

方法三:快排思想

注意,题目只需要返回最小的 k 个数字,而没有要求这 k 个数字一定是有序的。

期望复杂度为O(n):n+n/2+n/4+...n/n = 2n-1

最坏情况下的时间复杂度O(n^2)

代码

方法三

partition不用判断l<=r,因为k<=arr.size()

class Solution {
public:
    int partition(vector<int> &arr, int l, int r) {
        int pivot = arr[l];
        int i = l + 1;
        for (int j = i; j <= r; j++) {
            if (arr[j] < pivot) {
                swap(arr[j], arr[i]);
                i += 1;
            }
        }
        swap(arr[l], arr[i-1]);
        return i-1;
    }
    int calc(vector<int> &arr, int l, int r, int k) {
        int i = partition(arr, l, r);
        if (i - l == k) return i - 1;
        if (i - l + 1 == k) return i;
        if (k > i - l + 1) return calc(arr, i+1, r, k - (i-l+1));
        return calc(arr, l, i-1, k);
    }
    vector<int> getLeastNumbers(vector<int>& arr, int k) {
        int i = calc(arr, 0, arr.size()-1, k);
        vector<int> ans(arr.begin(), arr.begin()+i+1);
        return ans;
    }
};

方法二

class Solution {
public:
    vector<int> getLeastNumbers(vector<int>& arr, int k) {
        vector<int> ans;
        if (k == 0) return ans;
        priority_queue<int> q;
        for (int i = 0; i < k; ++i) {
            q.push(arr[i]);
        }
        for (int i = k; i < arr.size(); ++i) {
            if (arr[i] < q.top()) {
                q.pop();
                q.push(arr[i]);
            }
        }
        while (!q.empty()) {
            ans.push_back(q.top());
            q.pop();
        }
        // reverse(ans.begin(), ans.end());
        return ans;
    }
};

标签:arr,return,Offer,int,复杂度,个数,40,vector,ans
来源: https://www.cnblogs.com/huihao/p/16144659.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有