【快速选择算法】解决TopK问题中前K小的数字问题

在这里插入图片描述

1.前言

在一个数组中找到这个数组前K小的数字有三种方式:

  • 排序 O(N*logN)
  • 堆排序:建立一个k个大小的大堆(如果是找前K大的数字的话用小堆) O(N*logK)
  • 快速选择算法:原地交换数字,使得该数组前k个数字就是该数组前K小的数字 一般情况接近O(N),最差情况O(N^2)

2.题目简介

题目链接:LINK
在这里插入图片描述

3.求解思路

在这里插入图片描述
在这里插入图片描述

4.示例代码

class Solution {
public:
    vector<int> inventoryManagement(vector<int>& nums, int k) 
    {
        srand(time(nullptr));

        qsort(nums, 0, nums.size() - 1, k);
        return {nums.begin(), nums.begin() + k};
    }

    void qsort(vector<int>& nums, int begin, int end, int k)
    {
        if(begin >= end) return;

        //数组分三块
        int key = GetRandom(nums, begin, end);
        int left = begin - 1, right = end + 1, i = begin;
        while(i < right)
        {
            if(nums[i] < key)
            {
                swap(nums[i++], nums[++left]);
            }
            else if(nums[i] == key)
            {
                i++;
            }
            else //nums[i] > key
            {
                swap(nums[i], nums[--right]);
            }
        }

        //分情况讨论
        int a = left - begin + 1;
        int b = right - 1 - (left + 1) + 1;
        int c = end - begin + 1 - a - b;
        if(a >= k) qsort(nums, begin, left, k);
        else if(a + b >= k) return;
        else qsort(nums, right, end, k - a - b);
    }
    int GetRandom(vector<int>& nums, int begin, int end)
    {
        return nums[rand() % (end - begin + 1) + begin];
    }
};

在这里插入图片描述


EOF

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值