注意是第K个最大元素,因此在交换前进行判断的时候,和正常的快速排序比较符号相反。
class Solution {
public int findKthLargest(int[] nums,int k){
int length = nums.length;
if(length == 0)
return 0;
int left = 0,right = length - 1;
while(left < right){
int pos = partition(nums,left,right);
if(pos == k - 1)
break;
if(pos < k - 1)
left = pos + 1;
else
right = pos - 1;
}
return nums[k-1];
}
public int partition(int[] nums,int left,int right){
int temp = nums[left];
while (left < right){
while (left < right && nums[right] <= temp){
right--;
}
if(left < right) nums[left] = nums[right];
while (left < right && nums[left] >= temp){
left++;
}
if (left < right) nums[right] = nums[left];
}
nums[left] = temp;
return left;
}
}
基于堆的方案:
import java.util.Comparator;
import java.util.PriorityQueue;
public class Solution {
public int findKthLargest(int[] nums, int k) {
int len = nums.length;
// 使用一个含有 k 个元素的最小堆,PriorityQueue 底层是动态数组,为了防止数组扩容产生消耗,可以先指定数组的长度
PriorityQueue<Integer> minHeap = new PriorityQueue<>(k, Comparator.comparingInt(a -> a));
// Java 里没有 heapify ,因此我们逐个将前 k 个元素添加到 minHeap 里
for (int i = 0; i < k; i++) {
minHeap.offer(nums[i]);
}
for (int i = k; i < len; i++) {
// 看一眼,不拿出,因为有可能没有必要替换
Integer topElement = minHeap.peek();
// 只要当前遍历的元素比堆顶元素大,堆顶弹出,遍历的元素进去
if (nums[i] > topElement) {
// Java 没有 replace(),所以得先 poll() 出来,然后再放回去
minHeap.poll();
minHeap.offer(nums[i]);
}
}
return minHeap.peek();
}
}