📅  最后修改于: 2023-12-03 15:26:32.104000             🧑  作者: Mango
在一个未排序的数组中,找到第 k 个最小或最大元素。可以假设 k 总是有效的,即 1 ≤ k ≤ 数组长度。
最简单直观的方法是先排序,然后直接返回第 k 个元素。时间复杂度为 $O(n \log{n})$。
class Solution:
def findKthLargest(self, nums: List[int], k: int) -> int:
nums.sort()
return nums[-k]
class Solution:
def findKthSmallest(self, nums: List[int], k: int) -> int:
nums.sort()
return nums[k-1]
由于我们不需要对整个数组进行排序,因此可以考虑使用快速排序的思想,选择一个 pivot,将数组划分为小于 pivot 和大于 pivot 的两部分,然后再递归的处理其中一部分。具体算法如下:
时间复杂度:平均情况下为 $O(n)$,最坏情况下时间复杂度退化为 $O(n^2)$,但可以通过随机化 pivot 来避免最坏情况的发生。
class Solution:
def findKthLargest(self, nums: List[int], k: int) -> int:
def quickSelect(left, right, k):
if left == right:
return nums[left]
pivot_idx = random.randint(left, right)
pivot_idx = partition(left, right, pivot_idx)
if k == pivot_idx:
return nums[k]
elif k < pivot_idx:
return quickSelect(left, pivot_idx - 1, k)
else:
return quickSelect(pivot_idx + 1, right, k)
def partition(left, right, pivot_idx):
pivot_value = nums[pivot_idx]
nums[pivot_idx], nums[right] = nums[right], nums[pivot_idx]
store_idx = left
for i in range(left, right):
if nums[i] < pivot_value:
nums[store_idx], nums[i] = nums[i], nums[store_idx]
store_idx += 1
nums[right], nums[store_idx] = nums[store_idx], nums[right]
return store_idx
return quickSelect(0, len(nums) - 1, len(nums) - k)
class Solution:
def findKthSmallest(self, nums: List[int], k: int) -> int:
def quickSelect(left, right, k):
if left == right:
return nums[left]
pivot_idx = random.randint(left, right)
pivot_idx = partition(left, right, pivot_idx)
if k == pivot_idx:
return nums[k]
elif k < pivot_idx:
return quickSelect(left, pivot_idx - 1, k)
else:
return quickSelect(pivot_idx + 1, right, k)
def partition(left, right, pivot_idx):
pivot_value = nums[pivot_idx]
nums[pivot_idx], nums[right] = nums[right], nums[pivot_idx]
store_idx = left
for i in range(left, right):
if nums[i] < pivot_value:
nums[store_idx], nums[i] = nums[i], nums[store_idx]
store_idx += 1
nums[right], nums[store_idx] = nums[store_idx], nums[right]
return store_idx
return quickSelect(0, len(nums) - 1, k - 1)