算法通关村——数组中第K大的数字

数组中第K大的数字

1、题目描述

​ LeetCode215. 数组中的第K个最大元素。给定整数数组nums和整数k,请返回数组中第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

2、解题思路

​ 本题可以运用快速排序的思路,下图是快排中的一轮排序过程:

算法通关村——数组中第K大的数字_第1张图片

​ 在一轮的快排结束后,基准元素左侧的元素都是比它小的,右侧的元素都是比它大的,我们可以利用这个特点。具体来说,我们可以知道上图中基准元素在一轮快排后的索引是3,所以递增排序后,这个紫色的方块一定是第四大的元素。如果要找第二大的元素,就一定会去紫色元素右边的橙色元素中找;如果要找第六大的元素,就一定会去紫色原色左边的绿色元素中找,而不需要的那部分就不用管了。

3、代码实现

​ 用java给出本题的代码如下:

public static int quickSelect(int[] nums, int l, int r, int k) {
    if (l == r) return nums[k];
    int x = nums[l], i = l - 1, j = r + 1;
    while(i < j) {
        do i++; while (nums[i] < x);
        do j--; while (nums[j] > x);
        if (i < j) {
            int tmp = nums[i];
            nums[i] = nums[j];
            nums[j] = tmp;
        }
    }
    
    if (k <= j) return quickSelect(nums, l, j, k);
    else return quickSelect(nums, j + 1, r, k);
}

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

​ 为什么findKthLargest中传入quickSelect的是n-k而不是k?

​ 因为题目要求的是找出第k大的元素,如果quickSelect方法中返回的是_nums[k]的话,那返回就是排好序的数组中的第k-1个元素,如果返回的是__nums[n-k]的话,那返回的就是排好序的数组中从右往左的第k个元素,因为是递增序列,所以就是第k大的元素。

​ 例如对数组[3,2,1,5,6,4],返回第2大的元素,在调用quickSelect方法时传入的k参数是n-2=4,那最后在结束快排后,返回的就是一个递增数组的nums[4],即从右往左数的第二个元素,也就是第二大的元素。

你可能感兴趣的:(排序算法,算法,排序算法,数据结构)