剑指Offer JZ29 最小的K个数 C++实现

题目描述

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

解题思路


方法一:排序

1、思路:直接对数组进行排序,然后返回前K个元素。

2、代码:

class Solution {
public:
    vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
        if (input.empty() || !k || k > input.size()) return vector<int> ();
        sort(input.begin(), input.end());
        return vector<int> (input.begin(), input.begin() + k);
    }
};

3、复杂度:

时间复杂度:O(nlog_2n);

空间复杂度:O(1)。


方法二:优先队列

1、思路:开一个长度为K的优先队列,初始化为数组前K个元素,优先队列默认是大顶堆,队列内元素从大到小排序,大元素优先出队,元素在入队的过程中会自动排好序。然后就可以开始遍历数组:

  • 若数组当前元素大于优先队列队顶元素,则不做处理,继续遍历数组下一元素;
  • 若数组当前元素小于优先队列队顶元素,则该元素入队,队顶元素出队。

遍历完数组所有元素后,优先队列里的K个元素就是数组中最小的K个元素。

2、代码:

class Solution {
public:
    vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
        vector<int> ret (k);
        if (input.empty() || !k || k > input.size()) return vector<int> ();
        priority_queue<int> result;
        int i, count = k;
        for (i = 0; i < input.size(); i++) {
            if (count > 0) {
                result.push(input[i]);
                count--;
            } else {
                if (input[i] < result.top()) {
                    result.pop();
                    result.push(input[i]);
                }
            }
        }
        for (i = k - 1; i >= 0; i--) {
            ret[i] = result.top();
            result.pop();
        }
        return ret;
    }
};

3、复杂度:

时间复杂度:O(nlog_2K),对大小为K的堆进行排序需要O(log_2K),最坏情况下排序n次;

空间复杂度:O(K)。


方法三:快速排序

1、思路:利用快速排序思想,比较每次划分使用的基准数和第k小元素的关系来求解。

2、代码:

class Solution {
public:
    vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
        if (input.empty() || !k || k > input.size()) return vector<int> ();
        return quicksort(input, k, 0, input.size()-1);
    }
    vector<int> quicksort(vector<int>& input, int k, int l, int r) {
        int i = l, j = r;
        while (i < j) {
            while (i < j && input[j] >= input[l]) j--;
            while (i < j && input[i] <= input[l]) i++;
            swap(input[i], input[j]);
        }
        swap(input[i], input[l]);
        if (i > k) return quicksort(input, k, l, i-1);
        if (i < k) return quicksort(input, k, i+1, r);
        vector<int> ret(input.begin(), input.begin()+k);
        return ret;
    }
};

3、复杂度:

时间复杂度:O(n);

空间复杂度:O(log_{2}n)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值