TopK问题(快速选择)

TopK问题:就是给你一些数,让你从中找出最大/小的k个数

TopK问题有很多解法,如:堆、二叉排序树…
这里主要介绍利用了快速排序思想的快速选择做法
如果没有学过快速排序,最好先去学习快速排序

我们知道,快速排序每次partition之后都会把枢轴元素放到它的最终位置上,partition过程的操作如下:
每次选取一个元素 x 作为枢轴(一般选第一个元素),从后往前找比 x 小的第一个元素 y 放到 x 原来的位置上,再从前往后找比 x 大的第一个元素 z 放到 y 原来的位置上,最后把枢轴元素 x 放到 z 原来的位置上,这个位置就是 x 排完序的最终位置。此时 x 之前的元素都比 x 小,x 之后的元素都比 x 大。

因此,我们需要找最小的 k 个数(并不在意最小的 k 个数的顺序),就是看此时枢轴元素的前面是否是 k 个元素,如果大于 k,说明多了,就往左找,小于 k 个,说明少了,就往右找。

class Solution {
public:
    int partition(vector<int>& nums, int i, int j) {
        int pivot = nums[i];
        while (i < j) {
            while (i < j && nums[j] >= pivot) --j;
            nums[i] = nums[j];
            while (i < j && nums[i] <= pivot) ++i;
            nums[j] = nums[i];
        }
        nums[i] = pivot;
        return i;
    }

    int quickSelect(vector<int>& nums, int i, int j, const int& k) {
        if (i < j) {
            int pivotPos = partition(nums, i, j);
            if (pivotPos == k) return k;
            else if (pivotPos > k) quickSelect(nums, i, pivotPos - 1, k);
            else quickSelect(nums, pivotPos + 1, j, k);
        }
        return k;
    }

    vector<int> getLeastNumbers(vector<int>& arr, int k) {
        int i = quickSelect(arr, 0, arr.size() - 1, k);
        return vector<int>(arr.begin(), arr.begin() + i);
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值