1.问题思路
需要找到第K个最大的元素,这里我们可以使用大顶堆的思路,堆内只维护k个元素。
1)当前堆元素个数 < k,且当前元素 > 堆顶元素,则直接进入堆中。
2)当前堆元素个数 = k,且当前元素 > 堆顶元素,则移除堆顶元素,再加入堆中。
3)遍历完数组,第K个最大元素就是大顶堆堆底元素。
2.代码实现
public int findKthLargest(int[] nums, int k) {
PriorityQueue<Integer> queue = new PriorityQueue<>((o1, o2) -> o2-o1);
for (int i = 0; i < nums.length; i++) {
queue.offer(nums[i]);
}
int result = 0;
for (int i = 0; i < k; i++) {
result = queue.poll();
}
return result;
}
使用快速排序
class Solution {
public int findKthLargest(int[] nums, int k) {
// 第k个最大的元素则对应索引下标
//第一个大的数,下标就是len-1;
//类推第k个大的数,下标就是len-k;
//然后对下面进行界限初始化
int len=nums.length;
int target=len-k;
int left=0;
int right=len-1;
//这一步是
while(true){
int pivotIndex=partition(nums,left,right); //代码的核心部分,每次划分partition是自定义的函数,返回每次的划分
if(pivotIndex==target){
return nums[pivotIndex]; //这就是我们要找的值。
}else if(pivotIndex<target){
//此时说明 我们找的位置小于目标,因此目标在右侧
left=pivotIndex+1;
}else {
//此时说明大于目标,目标在左侧
right=pivotIndex-1;
}
}
}
public int partition(int[] nums, int left, int right) {
// 随机选择一个切分元素
int randomIndex = (int) (left + Math.random() * (right - left + 1));
swap(nums, left, randomIndex);
int pivotNum = nums[left];
int le = left + 1;
int ge = right;
while (le <= ge) {
// System.out.println("le: " + le + ", ge:" + ge);
if (nums[le] < pivotNum) {
le++;
continue;
}
if (nums[ge] > pivotNum) {
ge--;
continue;
}
swap(nums, le, ge);
le++;
ge--;
}
// System.out.println("le: " + le + ", ge: " + ge);
// 将privotIndex与ge位置进行交换
// 这里ge和le重合的情况, 此时left与le、ge交换都是可以的
// ge和le不重合, 此时ge一定在pivot左边, 只能与ge交换
swap(nums, left, ge);
return ge;
}
private void swap(int[] nums, int src, int target) {
int tmp = nums[target];
nums[target] = nums[src];
nums[src] = tmp;
}
}
本文介绍了如何使用大顶堆数据结构以及快速排序算法来解决LeetCode中的第K个最大元素问题。首先用大顶堆保持数组中最大的k个元素,然后利用快速排序的partition方法调整堆,最终返回堆底元素即为第K个最大元素。
471

被折叠的 条评论
为什么被折叠?



