适用于求数组中的第K个最大元素
示例: 215. 数组中的第K个最大元素
快速排序的核心包括“哨兵划分” 和 “递归” 。
[2,4,1,0,3,5]
的快速排序流程。然而,对于包含大量重复元素的数组,每轮的哨兵划分都可能将数组划分为长度为 1 和 n?1 的两个部分,这种情况下快速排序的时间复杂度会退化至
O
(
N
2
)
O(N^2)
O(N2)
) 。
一种解决方案是使用「三路划分」,即每轮将数组划分为三个部分:小于、等于和大于基准数的所有元素。这样当发现第 k大数字处在“等于基准数”的子数组中时,便可以直接返回该元素。
为了进一步提升算法的稳健性,我们采用随机选择的方式来选定基准数。
class Solution:
def findKthLargest(self, nums, k):
def quick_select(nums, k):
# 随机选择基准数
pivot = random.choice(nums)
big, equal, small = [], [], []
# 将大于、小于、等于 pivot 的元素划分至 big, small, equal 中
for num in nums:
if num > pivot:
big.append(num)
elif num < pivot:
small.append(num)
else:
equal.append(num)
if k <= len(big):
# 第 k 大元素在 big 中,递归划分
return quick_select(big, k)
if len(nums) - len(small) < k:
# 第 k 大元素在 small 中,递归划分
return quick_select(small, k - len(nums) + len(small))
# 第 k 大元素在 equal 中,直接返回 pivot
return pivot
return quick_select(nums, k)
class Solution:
def findKthLargest(self, nums: List[int], k: int) -> int:
# 先将前k个元素入堆
heap = [nums[i] for i in range(0,k)]
heapq.heapify(heap)
for i in range(k,len(nums)):
if nums[i] > heap[0]:
heapq.heappop(heap) # 弹出堆顶元素
heapq.heappush(heap,nums[i]) # nums[i] 入堆
return heap[0]
参考资料:
https://leetcode.cn/problems/kth-largest-element-in-an-array/solutions/2361969/215-shu-zu-zhong-de-di-k-ge-zui-da-yuan-d786p/
https://leetcode.cn/problems/kth-largest-element-in-an-array/solutions/2559996/li-yong-dui-jie-jue-top-kwen-ti-by-kiski-1747/