力扣--分治(快速排序)算法题II:数组中的第K个最大元素(Top K问题),LCR159.库存管理III

上篇文章:力扣--分治(快速排序)算法题I:颜色分类,排序数组

目录

1.数组中的第K个最大元素

理解题意

算法原理

2.库存管理III

理解题意

算法原理


1.数组中的第K个最大元素

https://leetcode.cn/problems/kth-largest-element-in-an-array/description/

理解题意

此题为Top K中找第K个最大元素的问题,并且对时间复杂度有要求。

算法原理

本题为满足时间复杂度,所以使用快速排序的方式。

最核心的思路依旧同上一篇文章相同:数组分为三块+随机选择基准元素

当c >= key时,在right, r中找第K大

当c + b >= key时,返回key

当前两个不成立时,去l, left找第k - b - c大。

复制代码
class Solution 
{
public:
    int findKthLargest(vector<int>& nums, int k) 
    {
        srand(time(NULL));
        return qsort(nums, 0, nums.size() - 1, k);
    }

    int qsort(vector<int>& nums, int l, int r, int k)
    {
        if(l == r) return nums[l];
        // 随机数
        int key = getRandom(nums, l, r);
        // 分三步
        int i = l, left = l - 1, right = r + 1;
        while(i < right)
        {
            if(nums[i] < key) swap(nums[++left], nums[i++]);
            else if(nums[i] == key) i++;
            else swap(nums[--right], nums[i]);
        }

        // 分情况
        int c = r - right + 1, b = right - left - 1;
        if(c >= k) return qsort(nums, right, r, k);
        else if(b + c >= k) return key;
        else return qsort(nums, l, left, k - b - c);
    }

    int getRandom(vector<int>& nums, int left, int right)
    {
        return nums[rand() % (right - left + 1) + left];
    }
};

2.库存管理III

https://leetcode.cn/problems/zui-xiao-de-kge-shu-lcof/description/

理解题意

给定一个整数数组 stock 和一个整数 cnt(即 k),要求找出数组中 最小的 cnt 个元素。返回顺序不限。同样要求时间复杂度尽可能低。这道题是经典的求"前K小"元素合集。

算法原理

同样使用快速选择算法 + 三路划分。但因为这次是找 前 K 小 ,我们的关注点转移到了数组的左边区间(小于 key 的区间)。

三路划分区间分布: [l, left] (全部 < key) | [left+1, right-1] (全部 == key) | [right, r] (全部 > key)

a = left - l + 1 (小于 key 的元素个数) 设 b = right - left - 1 (等于 key 的元素个数)

  1. a > cnt 时: 最小的 cnt 个元素全部都在 < key 的区间内。递归在 [l, left] 中找最小的 cnt 个元素。

  2. a + b >= cnt 时: < key== key 的元素总数已经达到或超过了 cnt。因为题目不要求输出顺序,此时数组左端的 cnt 个元素已经是最小的了,直接 return 结束划分。

  3. 前两种都不满足时: 左边和中间的元素全拿走也不够 cnt 个。我们需要保留前 a + b 个元素,并去右边 > key 的区间里再挑出剩下的 cnt - a - b 个元素。递归去 [right, r] 中找最小的 cnt - a - b 个元素。

代码:

复制代码
class Solution 
{
public:
    vector<int> inventoryManagement(vector<int>& stock, int cnt) 
    {
        srand(time(NULL));
        qsort(stock, 0, stock.size() - 1, cnt);
        return {stock.begin(), stock.begin() + cnt};
    }

    void qsort(vector<int>& stock, int l, int r, int cnt)
    {
        if(l >= r) return;

        int key = getRandom(stock, l, r);
        int i = l, left = l - 1, right = r + 1;
        while(i < right)
        {
            if(stock[i] < key) swap(stock[++left], stock[i++]);
            else if(stock[i] == key) i++;
            else swap(stock[--right], stock[i]);
        }

        int a = left - l + 1, b = right - left - 1;
        if(a > cnt) qsort(stock, l, left, cnt);
        else if(a + b >= cnt) return;
        else qsort(stock, right, r, cnt - a - b);
    }

    int getRandom(vector<int>& stock, int left, int right)
    {
        return stock[rand() % (right - left + 1) + left];
    }
};

本章完。

相关推荐
fpcc7 分钟前
C++编程实践——提高缓存的命中
c++·缓存
小张成长计划..14 分钟前
【C++】37:IO库(扩展)
c++
qingyulee14 分钟前
集成学习、聚类算法
算法·聚类·集成学习
Cx330❀15 分钟前
【Qt 核心机制篇】深度解析 Qt 信号与槽(Signals & Slots)机制:从底层原理、实战演练到 Lambda 进阶
linux·开发语言·c++·人工智能·qt·ubuntu
学习,学习,在学习15 分钟前
Modbus TCP同步通信方式实现异步级效率
网络·c++·qt·网络协议·tcp/ip·qt5
lqqjuly17 分钟前
机器人状态估计与 SLAM—概率推理到 simultaneous Localization and Mapping
算法·机器人
Cx330❀19 分钟前
【Linux网络】从零构建高性能UDP服务器:从Echo到英译汉业务级实现
大数据·linux·服务器·开发语言·网络·c++·udp
sali-tec20 分钟前
C# 基于OpenCv的视觉工作流-章79-单位转换
图像处理·人工智能·opencv·算法·计算机视觉
兰令水21 分钟前
leecodecode【双指针题2】【2026.5.26打卡-java版本】
java·开发语言·算法
不吃土豆的马铃薯21 分钟前
TCP 三次握手 / 四次挥手详解
服务器·开发语言·网络·c++·网络协议·tcp/ip