Leetcode——数组中的第K个最大元素
Posted Yawn,
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Leetcode——数组中的第K个最大元素相关的知识,希望对你有一定的参考价值。
1. 题目
2. 题解
(1)直接排序
public class Solution {
public int findKthLargest(int[] nums, int k) {
int len = nums.length;
Arrays.sort(nums);
return nums[len - k];
}
}
(2)利用快排(直接快排还超级超级慢)
class Solution {
public int findKthLargest(int[] nums, int k) {
quickSort(nums, 0, nums.length - 1);
int count = 0;
for(int i = nums.length - 1; i >=0; i--){
count++;
if(count == k)
return nums[i];
}
return 0;
}
private void quickSort(int[] arr, int left, int right) {
// 子数组长度为 1 时终止递归
if (left >= right) return;
// 哨兵划分操作(以 arr[l] 作为基准数)
int i = left, j = right;
while (i < j) {
while (i < j && arr[j] >= arr[left]) j--;
while (i < j && arr[i] <= arr[left]) i++;
swap(arr, i, j);
}
swap(arr, i, left);
// 递归左(右)子数组执行哨兵划分
quickSort(arr, left, i - 1);
quickSort(arr, i + 1, right);
}
private void swap(int[] arr, int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
(3)快排(改善)
- 由此可以发现每次经过「划分」操作后,我们一定可以确定一个元素的最终位置,即 x 的最终位置为。
- 所以只要某次划分的 q 为倒数第 k 个下标的时候,我们就已经找到了答案。
public class Solution {
public int findKthLargest(int[] nums, int k) {
int len = nums.length;
int left = 0;
int right = len - 1;
// 转换一下,第 k 大元素的索引是 len - k
int target = len - k;
while (true) {
int index = partition(nums, left, right);
if (index == target) {
return nums[index];
} else if (index < target) {
left = index + 1;
} else {
right = index - 1;
}
}
}
/**
由此可以发现每次经过「划分」操作后,我们一定可以确定一个元素的最终位置,即 x 的最终位置为。
所以只要某次划分的 q 为倒数第 k 个下标的时候,我们就已经找到了答案。
*/
public int partition(int[] arr, int left, int right) {
// 哨兵划分操作, left为哨兵
int i = left, j = right;
while (i < j) {
while (i < j && arr[j] >= arr[left]) j--;
while (i < j && arr[i] <= arr[left]) i++;
swap(arr, i, j);
}
swap(arr, i, left);
// 递归左(右)子数组执行哨兵划分
return i;
}
private void swap(int[] nums, int index1, int index2) {
int temp = nums[index1];
nums[index1] = nums[index2];
nums[index2] = temp;
}
}
(4)优先队列
优先队列的思路是很朴素的。因为第 K 大元素,其实就是整个数组排序以后后半部分最小的那个元素。因此,我们可以维护一个有 K 个元素的最小堆:
1、如果当前堆不满,直接添加;
2、堆满的时候,如果新读到的数小于等于堆顶,肯定不是我们要找的元素,只有新都到的数大于堆顶的时候,才将堆顶拿出,然后放入新读到的数,进而让堆自己去调整内部结构。
public class Solution {
public int findKthLargest(int[] nums, int k) {
int len = nums.length;
// 使用一个含有 len 个元素的最小堆,默认是最小堆,可以不写 lambda 表达式:(a, b) -> a - b
PriorityQueue<Integer> minHeap = new PriorityQueue<>(len, (a, b) -> a - b);
for (int i = 0; i < len; i++) {
minHeap.add(nums[i]);
}
for (int i = 0; i < len - k; i++) {
minHeap.poll();
}
return minHeap.peek();
}
}
以上是关于Leetcode——数组中的第K个最大元素的主要内容,如果未能解决你的问题,请参考以下文章
LeetCode 215. 数组中的第K个最大元素 | Python