库存管理III ---- 分治-快排

题目链接

题目:

分析:

  • 这道题本质上是一个topK问题, 我们能够想到三种解决办法
    解法一: 排序
    解法二: 堆
    解法三: 快速选择排序, 时间复杂度最好, 而且题目要求返回的顺序不限, 所以这个方法最好

  • 数组中的第K个最大元素 ---- 分治-快排-CSDN博客, 我们在这道题中学习了快速选择排序, 这道题要求的是返回第K大的元素, 而这道题要的是前K个小的元素, 我们想到, 找第K大的元素, K左边的元素一定是<=K, K右边的元素一定是>=K,但是是无序的, 与这道题的要求恰好相同

  • 那么我们想要前K小的元素, 只需要创建一个数组, 来存储K前面的元素即可, 所以这道题和上一道题其实是相同的, 这道题只是找第K小的元素

  • 那么在后面的判断条件中, 我们还是设每一块区域元素个数为a,b,c

  • 情况一: 如果第k个最小元素落在<key的区间, 说明此时a一定是>=k的, 此时只需要去[l, left]区间去找第k个最小元素即可

  • 情况二: 如果第k个最小元素落在=key的区间, 那么b+c一定是>=k的, 此时只需要返回key即可, 因为这个区间都是key

  • 情况三: 如果不是上述两种情况, 那么第k个最小元素一定落在>key的区间, , 此时需要去[right, r]区间去找, 但是我们要找的是第k-b-c小的元素, 因为我们舍去了=key和<key的区间

代码:

java 复制代码
class Solution {
    public int[] inventoryManagement(int[] stock, int cnt) {
        qsort(stock, 0, stock.length - 1, cnt);
        int[] ret = new int[cnt];
        for (int i = 0; i < cnt; i++) {
            ret[i] = stock[i];
        }
        return ret;
    }

    public void qsort(int[] nums, int l, int r, int k) {
        if (l >= r)
            return;
        int left = l - 1;
        int right = r + 1;
        int i = l;
        int key = nums[new Random().nextInt(r - l + 1) + l];
        while (i < right) {
            if (nums[i] < key)
                swap(nums, i++, ++left);
            else if (nums[i] == key)
                i++;
            else
                swap(nums, i, --right);
        }
        int a = left - l + 1;
        int b = right - left - 1;
        if (a > k)
            qsort(nums, l, left, k);
        else if (a + b >= k)
            return;
        else
            qsort(nums, right, r, k - a - b);
    }

    public void swap(int[] nums, int i, int j) {
        int tmp = nums[i];
        nums[i] = nums[j];
        nums[j] = tmp;
    }
}
相关推荐
ChoSeitaku3 分钟前
链表循环及差集相关算法题|判断循环双链表是否对称|两循环单链表合并成循环链表|使双向循环链表有序|单循环链表改双向循环链表|两链表的差集(C)
c语言·算法·链表
DdddJMs__1359 分钟前
C语言 | Leetcode C语言题解之第557题反转字符串中的单词III
c语言·leetcode·题解
Fuxiao___12 分钟前
不使用递归的决策树生成算法
算法
我爱工作&工作love我17 分钟前
1435:【例题3】曲线 一本通 代替三分
c++·算法
白-胖-子1 小时前
【蓝桥等考C++真题】蓝桥杯等级考试C++组第13级L13真题原题(含答案)-统计数字
开发语言·c++·算法·蓝桥杯·等考·13级
workflower1 小时前
数据结构练习题和答案
数据结构·算法·链表·线性回归
好睡凯1 小时前
c++写一个死锁并且自己解锁
开发语言·c++·算法
Sunyanhui11 小时前
力扣 二叉树的直径-543
算法·leetcode·职场和发展
一个不喜欢and不会代码的码农1 小时前
力扣105:从先序和中序序列构造二叉树
数据结构·算法·leetcode
前端郭德纲1 小时前
浏览器是加载ES6模块的?
javascript·算法