假设数组为nums,其长度为length,大于0;k的取值总是合理的。
方法1:排序法
对数组进行排序,如果是正序,则取索引为 [length-k] 的值;如果是倒叙,则取索引为 [k-1] 的值。
方法2:选择排序法
将数组分为已排序和未排序两部分,每次从未排序中选择最大的元素,放到已排序部分的最末位置,只需进行k次操作,便可得到第k个大的元素,即索引为 [k-1] 的值。
方法3:分治法(借助快排思想)
从数组中随机选择一个数,将大于等于该数的放到该数的左侧,小于该数的放到该数的右侧。假设该数在调整之后的数组中的索引为pivot。如果k-1 == pivot,则第k个最大元素的值为nums[pivot];如果k-1 > pivot,则根据上述方法,在 [pivot+1,length-1] 范围内查找第k个最大值;如果k-1 < pivot,则根据上述方法在 [0, pivot] 范围内查找第k个最大值。
方法4:最大最小堆法
a、最小堆
建立一个只有k个元素的最小堆,假设取了 [0, k-1] 的元素构建了最小堆,然后遍历 [k, length-1] 的元素,如果该原素大于堆顶元素,则弹出堆顶元素,将该原素加入最小堆。遍历完所有元素之后,最小堆中存储的k个元素是数组中最大的前k个,因为堆顶元素是最小的,那么堆顶元素也就是第k个最大的元素。
b、最大堆
建立一个只有 length-k+1 个元素的最大堆,假设取了 [0, length-k] 的元素建了最大堆,然后遍历 [length-k, length-1] 的元素,如果该元素大于堆顶元素,则弹出堆顶原元素,加入该元素。遍历完所有元素之后,最大堆种存储的 length-k+1 个元素是数组中最小的前 length-k+1个,因为堆顶元素最大,那么堆顶元素也就是第k个最大的元素。
import heapq
def findKthLargest(self, nums: List[int], k: int) -> int:
#排序法
nums.sort(reverse=True) # 倒叙
return nums[k-1]
nums.sort() # 正序
return nums[len(nums) - k]
# 选择排序法
if not nums:
return -1
# 选择排序法
length = len(nums)
for idx_i in range(k):
temp_idx = idx_i
for idx_j in range(idx_i+1, length):
if nums[idx_j] > nums[temp_idx]:
temp_idx = idx_j
nums[idx_i], nums[temp_idx] = nums[temp_idx], nums[idx_i]
return nums[k-1]
# 分治法
length = len(nums)
def partition(start, end):
temp_idx = start
val = nums[end]
for idx in range(start, end):
if nums[idx] >= val:
if idx != temp_idx:
nums[temp_idx], nums[idx] = nums[idx], nums[temp_idx]
temp_idx += 1
nums[temp_idx], nums[end] = nums[end], nums[temp_idx]
return temp_idx
def divide_conquer(start, end):
if start >= end:
return nums[start]
pivor = partition(start, end)
if k-1 == pivor:
return nums[pivor]
elif k-1 > pivor:
return divide_conquer(pivor+1, end)
else:
return divide_conquer(start, pivor-1)
return divide_conquer(0, length-1)
# 最小堆
min_heap = list()
length = len(nums)
for idx in range(k):
heapq.heappush(min_heap, nums[idx])
for idx in range(k, length):
if nums[idx] > min_heap[0]:
heapq.heappop(min_heap)
heapq.heappush(min_heap, nums[idx])
return min_heap[0]
# 最大堆
max_heap = list()
length = len(nums)
capacity = length -k +1
for idx in range(capacity):
heapq.heappush(max_heap, -nums[idx])
for idx in range(capacity, length):
if -nums[idx] > max_heap[0]:
heapq.heappop(max_heap)
heapq.heappush(max_heap, -nums[idx])
return -max_heap[0]