数组中第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、解题思路
本题可以运用快速排序的思路,下图是快排中的一轮排序过程:
在一轮的快排结束后,基准元素左侧的元素都是比它小的,右侧的元素都是比它大的,我们可以利用这个特点。具体来说,我们可以知道上图中基准元素在一轮快排后的索引是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],即从右往左数的第二个元素,也就是第二大的元素。