有两种思路,一种是快速选择法,一种是优先队列(最小堆)。
快选:
public class Solution {
public int findKthLargest(int[] a, int k) {
int n = a.length;
int p = quickSelect(a, 0, n - 1, n - k + 1);
return a[p];
}
// return the index of the kth smallest number
int quickSelect(int[] a, int lo, int hi, int k) {
// use quick sort's idea
// put nums that are <= pivot to the left
// put nums that are > pivot to the right
int i = lo, j = hi, pivot = a[hi];
while (i < j) {
if (a[i++] > pivot) swap(a, --i, --j);
}
swap(a, i, hi);
// count the nums that are <= pivot from lo
int m = i - lo + 1;
// pivot is the one!
if (m == k) return i;
// pivot is too big, so it must be on the left
else if (m > k) return quickSelect(a, lo, i - 1, k);
// pivot is too small, so it must be on the right
else return quickSelect(a, i + 1, hi, k - m);
}
void swap(int[] a, int i, int j) {
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
}
class Solution {
public int findKthLargest(int[] nums, int k) {
int left = 0, right = nums.length - 1;
k = nums.length - k;
while (left < right) {
int rank = partition(left, right, nums);
if (rank < k) {
left = rank + 1;
} else {
right = rank;
}
}
return nums[left];
}
private int partition(int left, int right, int[] nums) {
int mid = left + (right - left) / 2, pivot = nums[mid], i = left;
swap(mid, right, nums);
for (int j = left; j < right; j++) {
if (pivot > nums[j]) {
swap(i, j, nums);
i++;
}
}
swap(i, right, nums);
return i;
}
private void swap(int i, int j, int[] nums) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}
优先队列:
class Solution {
public int findKthLargest(int[] nums, int k) {
PriorityQueue<Integer> minHeap = new PriorityQueue<>(k);
for (int i = 0; i < nums.length; i++) {
if (i < k) {
minHeap.offer(nums[i]);
} else if (nums[i] > minHeap.peek()) {
minHeap.poll();
minHeap.offer(nums[i]);
}
}
return minHeap.peek();
}
}
class Solution {
public int findKthLargest(int[] nums, int k) {
PriorityQueue<Integer> pq = new PriorityQueue<Integer>();
for(int i=0;i<nums.length;i++) {
pq.offer(nums[i]);
if (pq.size() > k)
pq.poll();
}
return pq.peek();
}
}