215. 数组中的第K个最大元素
215. 数组中的第K个最大元素
题目链接:215. 数组中的第K个最大元素
题目描述
给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。
请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。
你必须设计并实现时间复杂度为 $O(n)$ 的算法解决此问题。
核心思考:快速选择(Quickselect)算法
要在 $O(n)$ 的期望时间内求出第 $k$ 大元素,常规的排序($O(n \log n)$)是不符合要求的。最优解法是采用快速选择(Quickselect),它是快速排序的一种变体。
- 基本思想:
- 快速排序的
partition(切分)操作会将数组分成两部分:一部分小于基准值(pivot),一部分大于基准值。 partition返回的下标i意味着当前基准值排好序后在数组中的绝对位置。- 寻找“第 $k$ 大个元素”,即寻找排序后下标为
n - k的元素(假设升序)。
- 快速排序的
- 分治策略:
- 如果
i == target_index,我们直接找到了目标值。 - 如果
i > target_index,说明目标值在左半部分,我们只需对左侧继续递归搜索。 - 如果
i < target_index,说明目标值在右半部分,我们只需对右侧继续递归搜索。
- 如果
- 随机化优化:
- 为了防止在极端不平衡的数据(如已排序数组)下退化为 $O(n^2)$,代码采用了
randint随机选择基准值,保证期望时间复杂度为 $O(n)$。
- 为了防止在极端不平衡的数据(如已排序数组)下退化为 $O(n^2)$,代码采用了
解题思路 (Python)
1 | class Solution: |
复杂度分析
- 时间复杂度:期望 $O(N)$。由于我们每次只需处理一边(而不是快排的两边都处理),其递推关系为 $T(n) = T(n/2) + O(n)$,根据主定理,结果为线性。
- 空间复杂度:$O(1)$。我们直接在原数组上进行交换和指针索引。