题目
在未排序的数组中找到第 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 ≤ 数组的长度。
方案一(堆)
class Solution:def findKthLargest(self, nums: List[int], k: int) -> int:heap = nums[:k]heapq.heapify(heap)for i in range(k, len(nums)):if nums[i] > heap[0]: # 比堆中最小元素大heapq.heapreplace(heap, nums[i])return heap[0]
或
class Solution:def findKthLargest(self, nums: List[int], k: int) -> int:return heapq.nlargest(k, nums)[-1]
方案二(分治)
class Solution:def findKthLargest(self, nums: List[int], k: int) -> int:# 快排思想+问题转化:第 k 个最大元素也就是第 N - k 个最小元素def partition(left, right, pivot_index):pivot = nums[pivot_index]# 将 pivot 移到最后nums[right], nums[pivot_index] = nums[pivot_index], nums[right]# 将小于 pivot 的移动在前面store_index = leftfor i in range(left, right):if nums[i] < pivot:nums[i], nums[store_index] = nums[store_index], nums[i]store_index += 1# 最后一个节点为分界点nums[right], nums[store_index] = nums[store_index], nums[right]# 返回分区点return store_indexdef select(left, right, k_smallest):if left == right:return nums[left]pivot_index = random.randint(left, right)pivot_index = partition(left, right, pivot_index)if k_smallest == pivot_index:return nums[pivot_index]elif k_smallest < pivot_index:return select(left, pivot_index - 1, k_smallest)else:return select(pivot_index + 1, right, k_smallest)return select(0, len(nums) - 1, len(nums) - k)
