难度中等282收藏分享切换为英文关注
通过次数
53,217
提交次数
90,374
在未排序的数组中找到第 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 ≤ 数组的长度。
( 数组中的第 k 个最大元素 = 找出最大的前 k 个数 )
瞬间想到:堆排序,或者快排(分治算法)。
这里采用堆排序来解决,创建小顶堆,堆顶的元素为最小的,只要小于最小的就进入队列。
实现步骤:
1.创建大小为 k 的小顶堆遍历数组。
2.大于最小的就进行替换。
3.通过堆的特性,每次替换之后重新再进行比较,堆顶依旧最小。
4.堆顶就是第 k 大的元素!!!
( 个人觉得讲解最简单的博主了,要带着问题去看(1)为什么要使用小顶堆(2)如何通过小顶堆求前k个元素 )
参考博主:https://blog.csdn.net/qq_37934101/article/details/81540637
以下是我实现的代码(为了简便,易于理解只用了C语言),
堆排序参考百度百科!
代码:
#include <stdlib.h>
#include <stdio.h>
void swap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
void minHeap(int *arr, int start, int end) {
int dad = start;
int son = dad * 2 + 1;
while (son <= end) {
if (son + 1 <= end && arr[son] > arr[son + 1]) {
son++;
}
if (arr[dad] < arr[son]) {
return;
}
else {
swap(&arr[dad], &arr[son]);
dad = son;
son = dad * 2 + 1;
}
}
}
void heap_sort(int *arr, int len) {
for (int i = len / 2 - 1; i >= 0; i--) {
minHeap(arr, i, len - 1);
}
for (int i = len - 1; i > 0; i--) {
swap(&arr[0], &arr[i]);
minHeap(arr, 0, i-1);
}
}
void buildMinHeap(int *arr, int len) {
for (int i = len / 2 - 1; i >= 0; i--) {
minHeap(arr, i, len - 1);
}
}
/* 获取前K的数据 */
int findKthLargest(int* nums, int numsSize, int k) {
if (numsSize < k || k <= 0)
return -1;
int topK;
int *heap = (int *)malloc(sizeof(int)*k);
for (int i = 0; i < k; i++) {
heap[i] = nums[i];
}
/* 建立最小堆 */
buildMinHeap(heap, k);
for (int i = k; i < numsSize; i++) {
if (nums[i] >= heap[0]) {
heap[0] = nums[i];
minHeap(heap, 0, k - 1);
}
}
for (int i = k - 1; i >= 0; i--) {
printf("%d ",heap[i]);
}
printf("\n");
topK = heap[0];
free(heap);
return topK;
}
int main() {
int arr[] = { 3, 5, 3, 0, 8, 6, 1, 5, 8, 6, 2, 4, 9, 4, 7, 0, 1, 8, 9, 7, 3, 1, 2, 5, 9, 7, 4, 0, 2, 6 };
int len = (int) sizeof(arr) / sizeof(*arr);
printf("len: %d\n", len);
printf("%d\n", findKthLargest(arr, len, 5));
printf("%d\n", findKthLargest(arr, len, 7));
printf("%d\n", findKthLargest(arr, len, 13));
printf("%d\n", findKthLargest(arr, len, 20));
printf("%d\n", findKthLargest(arr, len, 29));
heap_sort(arr, len);
for (int i = 0; i < len; i++)
printf("%d ", arr[i]);
printf("\n");
system("pause");
return 0;
}