Leetcode215. 数组中的第K个最大元素(C语言)
算法-排序(堆):算法与数据结构参考
题目:
在未排序的数组中找到第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。例:
输入: [3,2,1,5,6,4] k = 2
输出: 5
思路:
构建K次大顶堆(算法时间复杂度为KlogN)。
大顶堆节点的元素都不小于其孩子:
左边子节点位置 = 当前父节点的两倍 + 1
右边子节点位置 = 当前父节点的两倍 + 2
代码:
void swap(int *a, int *b){
int c = *a;
*a = *b;
*b = c;
}
void heap_adjust(int *arr, int len, int index) { //构造大顶堆
if(index<0 || index>len || 2*index+1 >= len) return;
//保证有子节点的根节点进行构造
int max = 2*index+1; //当前节点左子节点序号
if(max+1 < len && arr[max+1] > arr[max]) max++; //向后比较,找出最大值
if(arr[max] > arr[index]){ //子节点比根节点大,交换
swap(&arr[max], &arr[index]);
heap_adjust(arr, len, max); //当前最大值节点为根,递归
}
}
int findKthLargest(int* arr, int len, int k){
int i;
for(i=len/2; i>=0; i--) heap_adjust(arr, len, i); //自底向上构造大顶堆
for(i=0; i<k; i++){ //每次将最大值放最后,进行k次
heap_adjust(arr, len-i, 0);
swap(&arr[0], &arr[len-i-1]);
}
return arr[len-k]; //倒数第k个数
}