给定整数数组 nums
和整数 k
,请返回数组中第 k
个最大的元素。
请注意,你需要找的是数组排序后的第 k
个最大的元素,而不是第 k
个不同的元素。
你必须设计并实现时间复杂度为 O(n)
的算法解决此问题。
示例 1:
输入: [3,2,1,5,6,4],
k = 2
输出: 5
示例 2:
输入: [3,2,3,1,2,4,5,5,6],
k = 4
输出: 4
思路:通过建立一个小根堆,大小为k,遍历一遍数组,不满k个时往里添加元素,满k个时删除堆顶元素,添加新的元素,遍历完成后堆顶即是第k大的元素。
class Solution {
public int findKthLargest(int[] nums, int k) {
PriorityQueue<Integer> queue = new PriorityQueue<>(k);
for (int i = 0; i < k; i++) {
queue.offer(nums[i]);
}
for (int i = k; i < nums.length; i++) {
if(nums[i] > queue.peek()){
queue.remove();
queue.offer(nums[i]);
}
}
return queue.peek();
}
}
第二种解法:快速选择,快速排序基于分治法,每次选择都会有一个元素放在最终正确的位置上,经过n - k次选择后即可找到第k大的元素。
class Solution {
int quickselect(int[] nums, int l, int r, int k) {
if (l == r) return nums[k];
int x = nums[l], i = l - 1, j = r + 1;
while (i < j) {
do i++; while (nums[i] < x);
do j--; while (nums[j] > x);
if (i < j){
int tmp = nums[i];
nums[i] = nums[j];
nums[j] = tmp;
}
}
if (k <= j) return quickselect(nums, l, j, k);
else return quickselect(nums, j + 1, r, k);
}
public int findKthLargest(int[] _nums, int k) {
int n = _nums.length;
return quickselect(_nums, 0, n - 1, n - k);
}
}
Comments NOTHING