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

54 阅读2分钟

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

中等

给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。

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

你必须设计并实现时间复杂度为 O(n) 的算法解决此问题。

 

示例 1:

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

示例 2:

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

 

提示:

  • 1 <= k <= nums.length <= 105
  • -104 <= nums[i] <= 104

快排

import java.util.Random;

class Solution {
    Random random = new Random();
    /*
    * 快排思想,包含分区和递归,最主要的是原地排序和小于划分元素。
    * 小于等于不行,因为会导致左边出现和划分元素相等的情况,第K小就达不到了。
    * 递归:都小于划分元素就够了,不需要严格有序,所以只需要跳到k所在区间继续划分。
    * */
    public int findKthLargest(int[] nums, int k) {
        return quickSelect(nums, 0, nums.length - 1, nums.length - k);
    }

    public int quickSelect(int[] nums, int left, int right, int k) {
        int partitionIdx = partition(nums, left, right);
        if (partitionIdx == k) {
            return nums[k];
        } else if (partitionIdx < k) {
            return quickSelect(nums, partitionIdx + 1, right, k);
        } else {
            return quickSelect(nums, left, partitionIdx - 1, k);
        }
    }

    public int partition(int[] nums, int left, int right) {
        int pivotIndex = left + random.nextInt(right - left + 1);
        int pivotValue = nums[pivotIndex];

        swap(nums, pivotIndex, right);  // 把 pivot 移到末尾
        int storeIdx = left;

        for (int i = left; i < right; i++) {
            if (nums[i] < pivotValue) {
                swap(nums, i, storeIdx++);
            }
        }

        swap(nums, storeIdx, right);  // 把 pivot 放到最终位置
        return storeIdx;
    }

    public void swap(int[] nums, int i, int j) {
        int t = nums[i];
        nums[i] = nums[j];
        nums[j] = t;
    }
}

小顶堆

import java.util.Random;

class Solution {
    Random random = new Random();
    /*
    * 小顶堆,要求第K大,那就是只需要维护K个长度的小顶堆,转化为获取该小顶堆的堆顶元素。
    * */
    public int findKthLargest(int[] nums, int k) {
        PriorityQueue<Integer> heap = new PriorityQueue<>();
        for(int i=0;i<nums.length;i++){
            heap.add(nums[i]);
            if(heap.size()>k)
                heap.poll();
        }
        return heap.peek();
    
    }

   
}