215. 数组中的第K个最大元素 ( 基于快排的选择算法 )

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

在这里插入图片描述


思路:

  1. 基于快排的选择方法
  2. 小顶堆


AC Code 基于快排的选择方法

class Solution {
    
    

    // 随机数
    Random random = new Random();

    public int findKthLargest(int[] nums, int k) {
    
    
        // 第 k 大
        int left = 0, right = nums.length - 1, kindex = nums.length - k;
        int ans = quickSelect(nums, left, right, kindex);
        return ans;
    }

    // 基于快排的选择算法
    public int quickSelect(int[] arr, int left, int right, int kindex) {
    
    
        int idx = randomPartition(arr, left, right);
        if(idx == kindex) return arr[idx];

        // else
        // 偏左  >> 往右区间靠
        // 递归
        return idx > kindex ? quickSelect(arr, left, idx - 1, kindex) 
        					: quickSelect(arr, idx + 1, right, kindex);
    }

    // 随机数分区
    public int randomPartition(int[] arr, int left, int right){
    
    
        // 随机数 > [left, right]
        int q = random.nextInt(right - left + 1) + left;
        
        // 交换位置
        swap(arr, q, right);
        int index = partition(arr, left, right);
        return index;
    }

    // 分区
    public int partition(int[] arr, int left, int right){
    
    
        // x 就是选到的随机数
        int x = arr[right], i = left;

        // 左右分
        for(int j = left; j < right; j++) {
    
     //  mark: lan
            if(arr[j] <= x) {
    
    
                // 放到区间左边
                swap(arr, i++, j);
            }
        }

        // 例子: for 循环后最终效果应该是 [2, 3, 1, 4, | 9, 6, 8, 7, x = 5]
        // 将 5 换回去中间
        swap(arr, i, right);

        return i;
    }
    

    // 交换
    public void swap(int[] arr, int x, int y){
    
    
        int tmp = arr[x];
        arr[x] = arr[y];
        arr[y] = tmp;
        // 这里不能用 ^ 来进行交换 >> 
        // 因为分区的时候(mark:lan),会有 x == y 的情况, 这时候会将 arr 中的元素变成 0
    }

}

时间复杂度: O ( N ) O(N) O(N)





AC Code 优先队列构建小顶堆

class Solution {
    
    
    public int findKthLargest(int[] nums, int k) {
    
    
        // topK 问题
        PriorityQueue<Integer> queue = new PriorityQueue<>(new Comparator<Integer>(){
    
    
            public int compare(Integer a, Integer b) {
    
    
                return b - a;
            }
        });
        int len = nums.length;

        for(int i = 0; i < len; i++) {
    
    
            queue.add(nums[i]);
        }

        for(int i = 1; i < k; i++) {
    
    
            queue.poll();
        }

        return queue.peek();
    }
}



猜你喜欢

转载自blog.csdn.net/qq_43765535/article/details/112915269
今日推荐