数组中第 K 大的元素

2024年8月28日 | 阅读 18 分钟

本文将教我们如何在未排序的数组中找到第 K 大的元素。有多种方法可以解决给定的问题。下面讨论了最佳实践。

问题 - 考虑一个包含 N 个元素的未排序数组。给定一个小于数组大小的数字 k;我们必须以最佳方式找到第 K 大的元素。

例如

方法 1: 最直接的方法是排序给定的数组并返回所需的值。我们可以使用堆排序或归并排序在 O(N Log N) 的时间内找到解决方案。

假设数组没有重复元素

在 C++ 中

示例输出

The 3th largest element = 15

在 C 语言中:

示例输出

The 4th largest element = 12

在 Python 中

示例输出

The 5th largest element = 8

C++ 代码

示例输出

My set = {2, 4, 5, 10, 12, 18, 22, 36, 54}
The 3th largest element = 22

Python 代码

输出

My set = {8, 9, 10, 12, 15, 17, 22, 26, 27, 28, 29}
The 5th largest element = 22

方法 3 - 使用最大堆

可以使用堆找到第 K 大的元素。这里,我们使用了最大堆;我们首先将给定数组转换为最大堆,然后用最后一个元素替换根,将堆大小减一,然后再次将其转换为最大堆。我们重复相同的步骤 k-1 次。之后,在根索引 = 0 处找到第 K 个元素。

C++ 代码

输出

The 2th largest element = 16

C 代码

输出

The 3th largest element = 12

方法 4 - 使用最小堆

在此方法中,我们创建一个包含 k 个元素的最小堆,其最小值(根元素)将是第 K 大值。如果数组中有超过 k 个元素,那么我们检查每个元素是否大于堆的根元素,我们将对所有剩余元素执行以下步骤。

  • 如果元素小于根,则意味着第 K 大值仍然是根元素,然后我们为下一个元素检查条件。
  • 如果元素大于根,则意味着根元素不是第 K 大值,我们将根替换为该元素,并在根索引处调用 min-heapify。
  • 执行结束时,我们将返回根元素,该元素将是第 K 大值。

此方法的 time complexity 为 T(n) = klogk + (n-k)logk

And the space complexity = O(k)

C++ 代码

输出

My array = {12, 15, 17, 23, 9, 16, 7, 45, 6, 42, 33}
The 5th largest value = 17

C 代码

输出

My array = {12, 15, 17, 23, 9, 16, 7, 45, 6, 42, 33, }
The 4th largest value = 23

方法 5 - 部分快速排序

在此方法中,我们利用快速排序的思想来查找数组中的第 K 大元素。我们知道,快速排序选择一个枢轴元素,将其放置在其正确的位置,然后递归地重复相同的过程,直到数组被排序。类似地,我们执行相同的步骤,但不是完全执行快速排序。当枢轴本身是第 K 大值时,我们将停止执行并打印所需值。此方法的 worst time complexity 为 O(n^2),average time complexity 为 O(N logN)。我们在比平均情况复杂度更短的时间内实现了所需的输出。

C++ 代码

输出

The array = [45, 66, 85, 69, 33, 25, 18, 12, 14, 13]
The 5th largest element = 33

C 代码

输出

The array = [75, 85, 69, 60, 37, 28, 35, 26, 11, 18]
The 4th largest element = 60

输出

My array = [78, 41, 33, 32, 25, 20, 15, 14, 12, 11]
The 6th largest element = 20