题目
在未排序的数组中找到第 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 ≤ 数组的长度。
解题思路
学过算法的应该清楚这题是使用快排的思想来解决。
第一步:利用快排的方法,每次取一个数num,把一个数组分为左右2堆,左边的比num小,右边的比num大,返回num在数组的位置index;
第二步:判断index和数组长度len-k的大小,如果index > nums.length-k则说明第k大的数在[l,index-1]之间,否则在[index+1,r]之间;
第三步:再回到第一步继续判断直到index==nums.length-k即可。
代码如下
class Solution {
public int findKthLargest(int[] nums, int k) {
int p = 0, r = nums.length-1;
if(p >= r) {
return nums[p];
}
int index = partition(nums, p, r);
while (index != nums.length-k) {
if (index > nums.length-k) {
r = index - 1;
} else {
p = index + 1;
}
index = partition(nums, p, r);
}
return nums[nums.length-k];
}
public int partition(int[] nums, int l, int r) {
//使用随机化的快速排序,会大大加快速度(leetcode的样例就是这么刁钻)
int random = l+(int)(Math.random()*(r-l));
swap(nums, l, random);
int x = nums[l];
int lo = l+1, hi = r;
while (lo <= hi) {
while (lo <= hi && nums[lo] < x) {
lo++;
}
while (lo <= hi && nums[hi] > x) {
hi--;
}
if (lo <= hi) {
swap(nums, lo++, hi--);
}
}
swap(nums, l, hi);
return hi;
}
//交换数组中的元素位置
public void swap(int[] nums, int n, int m) {
if (n == m) return;
int tmp = nums[n];
nums[n] = nums[m];
nums[m] = tmp;
}
}
提交结果
成功
显示详情
执行用时 : 3 ms, 在Kth Largest Element in an Array的Java提交中击败了97.95% 的用户
内存消耗 : 39 MB, 在Kth Largest Element in an Array的Java提交中击败了67.34% 的用户