74.数组中的第K个最大元素
给定整数数组 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
提示:
- 1 <= k <= nums.length <= 105
- -104 <= nums[i] <= 104
代码:
class Solution {
public int findKthLargest(int[] nums, int k) {
//heapSize为堆中元素个数
int heapSize = nums.length;
//构建最大堆
buildMaxHeap(nums,heapSize);
//执行k-1次提取最大值的操作
for(int i = nums.length - 1 ;(--k)>0;i--){
//将当前堆顶的最大值交换到数组末尾
swap(nums,0,i);
//堆大小减一,排除已找到的最大值
heapSize--;
//对新的堆顶元素进行调整,恢复堆的性质
maxHeapify(nums,0,heapSize);
}
//堆顶元素就是第K大的元素
return nums[0];
}
//构建最大堆
public void buildMaxHeap(int[] a,int heapSize){
//从最后一个非叶子节点开始,向前遍历
//最后一个非叶子节点的索引是heapSize/2-1
for(int i = heapSize/2-1;i>=0;i--){
//对每个非叶子节点进行堆化调整
maxHeapify(a,i,heapSize);
}
}
public void maxHeapify(int[] a,int i,int heapSize){
//计算左子节点的索引
int l = 2*i+1;
//计算右子节点的索引
int r = 2*i+2;
//初始化cur为当前节点
int cur = i;
//如果左子节点存在且大于当前节点
if(l<heapSize&&a[l]>a[cur])cur = l;
//如果右子节点存在且大于当前节点
if(r<heapSize&&a[r]>a[cur])cur = r;
//如果最大值不是当前节点
if(cur!=i){
//交换当前节点与最大值节点
swap(a,i,cur);
//递归地对交换后的子树进行堆化
maxHeapify(a,cur,heapSize);
}
}
//交换数组中两个元素的位置
public void swap(int[] a,int i,int j){
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}

浙公网安备 33010602011771号