快速选择(O(n),找到无序数组任意第k大的数字)

本文深入讲解了快速选择算法,一种平均时间复杂度为O(n)的高效算法,用于寻找无序数组中第n大的元素。通过随机化分区过程,算法确保了良好的平均性能。文章详细解释了算法的实现细节,并提供了完整的C++代码示例。
#include <vector>
#include <cstdlib>
using namespace std;

/*
 * 快速选择, O(n) 时间 找到无序数组 第n大的数字
 */



int partition(vector<int> &nums, int l, int r){
    // 随机选择作为主元的那个元素
    int rand_idx = rand() % (r-l+1) + l;
    swap(nums[l], nums[rand_idx]);

    int less = l, pivot = nums[l];
    for (int i = l + 1; i <= r; i++){
        if (nums[i] < pivot)
            swap(nums[i], nums[++less]);
    }

    swap(nums[l], nums[less]);
    return less;
}

int quick_select(vector<int> &nums, int n){
    if(n<=0 || nums.size() < n)
        return -1;

    n = n -1; // 转为下标
    int l = 0, r = nums.size()-1;
    int idx = partition(nums, l, r);
    while (idx != n)
    {
        if (n < idx)
            r = idx-1;
        else
            l = idx + 1;
        idx = partition(nums, l, r);
    }
    return nums[idx];
}

例题:

​ leetcode 215. 数组中的第K个最大元素 medium ​_speargod的博客-优快云博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值