题目链接
https://leetcode-cn.com/problems/kth-largest-element-in-an-array/
描述
在未排序的数组中找到第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,
而不是第 k 个不同的元素。
说明:
你可以假设 k 总是有效的,且 1 ≤ k ≤ 数组的长度。
示例
示例 1:
输入: [3,2,1,5,6,4] 和 k = 2
输出: 5
示例 2:
输入: [3,2,3,1,2,4,5,5,6] 和 k = 4
输出: 4
初始代码模板
class Solution {
public int findKthLargest(int[] nums, int k) {
}
}
代码
推荐下面的文章,两个方法都有讲解,第二个方法的洗牌算法就是看文章才加上去的:
https://labuladong.gitbook.io/algo/suan-fa-si-wei-xi-lie/3.3-qi-ta-suan-fa-pian/kuai-su-xuan-ze
优先队列
class Solution {
public int findKthLargest(int[] nums, int k) {
PriorityQueue<Integer> queue = new PriorityQueue<>();
for (int i = 0; i < nums.length; i++) {
queue.offer(nums[i]);
if (queue.size() > k) {
queue.poll();
}
}
return queue.peek();
}
}
快速选择
class Solution {
public int findKthLargest(int[] nums, int k) {
//因为利用的是快排思想,这里可以对数组进行打乱,尽量避免最坏情况
shuffle(nums);
//转换k,把找第k大转换成找到升序数组中下标值k的元素
k = nums.length - k;
int low = 0;
int high = nums.length - 1;
while (low <= high) {
int p = partition(nums, low, high);
if (p == k) {
return nums[p];
} else if (p > k) {
high = p - 1;
} else {
low = p + 1;
}
}
return -1;
}
private void shuffle(int[] nums) {
Random ran = new Random();
for (int i = nums.length - 1; i > 0; i--) {
swap(nums, ran.nextInt(i), i);
}
}
private void swap(int[] nums, int i, int j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
private int partition(int[] nums, int low, int high) {
int temp = nums[low];
while (low < high) {
while (low < high && nums[high] > temp) {
high--;
}
nums[low] = nums[high];
while (low < high && nums[low] <= temp) {
low++;
}
nums[high] = nums[low];
}
nums[low] = temp;
return low;
}
}