【LeetCode】215-数组中的第K个最大元素
阅读原文时间:2023年10月14日阅读:3

题目描述

在未排序的数组中找到第 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 ≤ 数组的长度。


解题思路

使用快速排序的思想来解题

每次选择数组中最后一个元素作为目标值pivot,然后从头到尾扫描数组,使< pivot的元素在pivot左边,>= pivot的元素在pivot右边,再计算pivot在数组中的位置,(递归地)调整下一次quickSelect的范围。pivot偏大,下次就在左边找第k个;pivot偏小,下次就在右边找第k-m个。

public int findKthLargest (int[] nums, int k) {
    int n = nums.length;
    int p = quickSelect(nums, 0, n - 1, n - k + 1);
    return nums[p];
}

// 此处的 k 是按从小到大排的顺序
// return the index of the kth smallest number
private int quickSelect (int[] nums, int lo, int hi, int k) {
    int i = lo;
    int j = hi;
    int pivot = nums[hi];
    // < pivot 放左边
    // >= pivot 放右边
    while (i < j) {
        if (nums[i++] > pivot) swap(nums, --i, --j);
    }
    swap(nums, i, hi); // 将 pivot 放入正确位置

    // 计算 pivot 在数组中的位置
    int m = i - lo + 1;

    if (m == k) return i;
    else if (m > k) return quickSelect(nums, lo, i - 1, k);
    else return quickSelect(nums, i + 1, hi, k - m);
}

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

心得体会

快速排序的关键是正确地切分数组。