题目
在未排序的数组中找到第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。
思路
找第k个最大元素很容易想到排序算法。该题可以使用堆排序进行排序,然后删除k-1个节点,即可以得到第k个最大元素。
具体的实现思路见代码注释。
代码
class Solution {
public int findKthLargest(int[] nums, int k) {
int heapSize=nums.length;
buildMaxHeap(nums,heapSize);//初始化大顶堆
for(int i=nums.length-1;i>=nums.length+1-k;i--){//删除k-1个节点,得到第k个最大值
swap(nums,0,i);
heapSize--;
maxHeapify(nums,0,heapSize);
}
return nums[0];
}
public void buildMaxHeap(int[] a, int heapSize){
for(int i=heapSize/2;i>=0;i--){//找到最底层的父节点,自底向上进行排序
maxHeapify(a,i,heapSize);
}
}
public void maxHeapify(int[] a, int i, int heapSize){
int l=i*2+1, r=i*2+2, largest=i;//标注父节点及其左右孩子
//找到父节点和左右节点三个节点中最大的值
if(l<heapSize&&a[l]>a[largest]){
largest=l;
}
if(r<heapSize&&a[r]>a[largest]){
largest=r;
}
if(largest!=i){//重新将该三个节点进行排序
swap(a,largest,i);
maxHeapify(a,largest,heapSize);//对修正后的序列进行排序,注释1
}
}
public void swap(int[] a, int i, int j){
int temp=a[i];
a[i]=a[j];
a[j]=temp;
}
}
注释1:
复杂度分析
- 时间复杂度:O(nlogn)
- 空间复杂度:O(logn)//递归造成的空间复杂度