LeetCode215 数组中的第K个最大元素

该博客介绍了如何通过三路快速排序算法来解决在未排序数组中找到第k个最大元素的问题。虽然三路快排通常效率较高,但作者指出对于这个特定问题,双路快排可能更为合适。示例展示了算法如何处理不同情况,并提供了代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在未排序的数组中找到第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。

示例 1:

输入: [3,2,1,5,6,4] 和 k = 2
输出: 5
示例 2:

输入: [3,2,3,1,2,4,5,5,6] 和 k = 4
输出: 4
说明:

你可以假设 k 总是有效的,且 1 ≤ k ≤ 数组的长度。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/kth-largest-element-in-an-array
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

使用了三路快排实现 但是对于这道题来讲双路快排要快一些。

class Solution {

    public int findKthLargest(int[] nums, int k) {
        Random rnd = new Random();
        return Sort(nums, 0, nums.length-1, rnd, k);
    }


    private static int Sort(int[] arr, int l, int r, Random rnd, int k) {

        if (l >= r){
            return  (r == k-1) ? arr[r] : -1;
        }
        int p = l + rnd.nextInt(r-l+1);
        swap(arr, l, p);

        // arr[l+1, lt] > 0  || arr[lt+1, i-1] =0 || arr[gt, r] < 0
        int lt = l, gt = r+1, i = l+1;
        while (i < gt) {
            if (arr[i] > arr[l]) {
                lt++;
                swap(arr, lt, i);
                i++;
            } else if (arr[i] == arr[l]) {
                i++;
            } else {
                gt--;
                swap(arr, gt, i);
            }
        }
        // 将l与lt交换
        swap(arr, l, lt);
        // 数组变为 arr[l, lt-1] > 0 || arr[lt, gt-1] = 0 || arr[gt, r] < 0
        if (lt <= k-1 && gt-1 >= k-1)
            return arr[lt];
        else if (lt < k-1) {
            return Sort(arr, gt, r, rnd, k);
        } else {
            return Sort(arr, l, lt-1, rnd, k);
        }
    }

    private static void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }

    public static void main(String[] args) {
        int[] arr = {3,3,3,3,3,3,3,3,3};
        System.out.println(new Solution().findKthLargest(arr, 8));
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值