【快速选择】Leetcode 215. 数组中的第K个最大元素

题目链接

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

思路

对于给定数组,求解第 \(k\) 大元素,且要求线性复杂度,正解为使用「快速选择」做法。

基本思路与「快速排序」一致,每次敲定一个基准值 \(x\),根据当前与 \(x\) 的大小关系,将范围在 \([l,r]\)\(nums[i]\) 划分为到两边。

同时利用,利用题目只要求输出第\(k\) 大的值,而不需要对数组进行整体排序,我们只需要根据划分两边后,第 \(k\) 大数会落在哪一边,来决定对哪边进行递归处理即可。

代码

class Solution{
    Random rand = new Random();

    public int findKthLargest(int[] nums, int k){

        return quickselect(nums, k, 0, nums.length - 1);
    }

    private int quickselect(int[] nums, int k, int left, int right){

        // use random to avoid O(n^2)
        int index = rand.nextInt(right - left + 1) + left;
        int flag = nums[index];
        nums[index] = nums[left];

        int i = left, j = right;
        while(i < j){
            while(i < j && nums[j] <= flag){
                j--;
            }
            nums[i] = nums[j];
            while(i < j && nums[i] >= flag){
                i++;
            }
            nums[j] = nums[i];
        }
        nums[i] = flag;

        if(i == k - 1){
            return nums[i];
        }else if(i < k - 1){
            return quickselect(nums, k, i + 1, right);
        }else{
            return quickselect(nums, k, left, i - 1);
        }
    }
}
posted @ 2023-01-02 21:48  Frodo1124  阅读(97)  评论(0编辑  收藏  举报