LeetCode-215. 数组中的第K个最大元素

8 篇文章 0 订阅
本文介绍了一种使用堆排序方法在未排序的数组中找到第K个最大的元素。通过创建一个小顶堆,不断遍历数组并替换堆顶元素,最终堆顶的元素即为第K大的元素。代码示例以C语言给出。
摘要由CSDN通过智能技术生成

215. 数组中的第K个最大元素

难度中等282收藏分享切换为英文关注

通过次数

53,217

提交次数

90,374

题目描述

评论 (437)

题解(100)New

提交记录

在未排序的数组中找到第 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;
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值