在未排序的數組中找到第 k 個最大的元素。請注意,你需要找的是數組排序後的第 k 個最大的元素,而不是第 k 個不同的元素。
示例 1:
輸入: [3,2,1,5,6,4] 和
k = 2
輸出: 5
示例 2:
輸入: [3,2,3,1,2,4,5,5,6] 和
k = 4
輸出: 4
說明:
你可以假設 k 總是有效的,且 1 ≤ k ≤ 數組的長度。
思路:
和劍指offer的最小的k個數差不多,這裏求第k大的元素可以看作轉換爲求第len-k+1小的元素,就和那題一模一樣了。
兩種解法,參考最小的k個數那篇:
/**
* @author yuan
* @date 2019/2/19
* @description 使用快排
*/
public class 數組中的第K個最大元素 {
public int findKthLargest(int[] nums, int k) {
// 找第k大的元素相當於找第len - k + 1小的元素
k = nums.length - k + 1;
int l = 0, r = nums.length - 1;
int index = partition(nums, l, r);
while (index != k - 1) {
if (index > k - 1) {
r = index - 1;
index = partition(nums, l, r);
} else {
l = index + 1;
index = partition(nums, l, r);
}
}
return nums[index];
}
private int partition(int[] a, int l, int r) {
int i = l, j = r;
int base = a[l];
while (i < j) {
while (i < j && a[j] >= base) {
--j;
}
while (i < j && a[i] <= base) {
++i;
}
if (i < j) {
swap(a, i, j);
}
}
swap(a, l, i);
return i;
}
private void swap(int[] a, int i, int j) {
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
使用最大堆:
import java.util.Comparator;
import java.util.PriorityQueue;
/**
* @author yuan
* @date 2019/2/20
* @description
*/
public class 數組中的第K個最大元素 {
public int findKthLargest(int[] nums, int k) {
int len = nums.length;
k = len - k + 1;
PriorityQueue<Integer> maxHeap = new PriorityQueue<>(len, Comparator.reverseOrder());
for (int i = 0; i < len; i++) {
if (maxHeap.size() < k) {
maxHeap.offer(nums[i]);
} else if (nums[i] < maxHeap.peek()) {
maxHeap.poll();
maxHeap.offer(nums[i]);
}
}
return maxHeap.peek();
}
}