📅  最后修改于: 2023-12-03 14:55:26.272000             🧑  作者: Mango
给定一个未排序的数组,需要找到其中第K个最小或最大的元素。例如,给定数组 [3, 7, 2, 1, 8, 6, 5, 4],需要找到其中第3个最小的元素,值为 3。
最简单的解决方案是先对数组进行排序,然后直接找到第K个元素。这个算法的时间复杂度为 $O(n \log n)$,其中 $n$ 为数组的长度。
我们可以使用快速排序中的 partition() 方法来找到数组中第K个最小(或最大)的元素。该方法的时间复杂度为 $O(n)$,其中 $n$ 为数组的长度。假设我们要找到第K个最小的元素。
因为每次将数组划分为两部分,所以算法的时间复杂度为 $O(n)$,其中 $n$ 为数组的长度。
def partition(nums, left, right):
pivot = nums[right]
i = left - 1
for j in range(left, right):
if nums[j] < pivot:
i += 1
nums[i], nums[j] = nums[j], nums[i]
nums[i+1], nums[right] = nums[right], nums[i+1]
return i+1
def kthSmallest(nums, k):
left, right = 0, len(nums)-1
while True:
pivot_index = partition(nums, left, right)
if pivot_index == k-1:
return nums[pivot_index]
elif pivot_index < k-1:
left = pivot_index + 1
else:
right = pivot_index - 1
我们可以使用一个大小为K的最大堆来解决这个问题。我们遍历一遍数组,将每个元素加入堆中,如果堆的大小超过K,则移除堆顶元素。遍历结束后堆顶元素即为第K个最小的元素。该方法的时间复杂度为 $O(n \log k)$,其中 $n$ 为数组的长度。
同理,如果要找到第K个最大的元素,我们可以使用一个大小为K的最小堆。
import heapq
def kthSmallest(nums, k):
heap = []
for num in nums:
heapq.heappush(heap, -num)
if len(heap) > k:
heapq.heappop(heap)
return -heap[0]
我们介绍了三种方法来找到未排序数组中的第K个最小或最大元素:排序、快速选择和堆。其中,快速选择和堆的时间复杂度都为 $O(n)$ 或 $O(n\log k)$,要比排序的时间复杂度 $O(n \log n)$ 更优秀。在实际问题中,我们可以根据具体情况来选择哪种方法。