题目链接
https://leetcode.cn/problems/kth-largest-element-in-an-array/description/
题目描述
解法快速排序
使用快速选择算法(QuickSelect)来实现时间复杂度为 O(n) 的解法。
快速选择算法是基于快速排序的算法,它的基本思路是通过划分(partition)将数组分为两部分,一部分大于等于基准值,一部分小于基准值。如果基准值的下标等于 k-1,那么基准值就是数组排序后的第 k 个最大元素。否则,根据基准值的下标与 k-1 的关系,递归在左半部分或右半部分继续查找。
代码
func findKthLargest(nums []int, k int) int {
left, right := 0, len(nums)-1
for left <= right {
pivot := partition(nums, left, right)
if pivot == k-1 {
return nums[pivot]
} else if pivot < k-1 {
left = pivot + 1
} else {
right = pivot - 1
}
}
return -1
}
func partition(nums []int, left, right int) int {
pivot := nums[left]
for left < right {
for left < right && nums[right] <= pivot {
right--
}
nums[left] = nums[right]
for left < right && nums[left] >= pivot {
left++
}
nums[right] = nums[left]
}
nums[left] = pivot
return left
}
可以测试一下:
func main() {
nums := []int{3, 2, 1, 5, 6, 4}
k := 2
fmt.Println(findKthLargest(nums, k)) // 输出 5
}
讲解
上述代码使用了快速选择算法,它是快速排序的一个变种。快速选择算法可以在O(n)的时间复杂度内,找到一个无序数组中第k大的数。
该算法的主要思路是:
选取数组中任意一个元素作为枢纽元(pivot)。
将数组中小于pivot的元素放在其左侧,大于pivot的元素放在其右侧。
如果pivot的位置是k,则找到了第k大的数。
如果pivot的位置小于k,则在右侧继续查找第k大的数,否则在左侧继续查找第k大的数。
该算法的具体实现是使用了递归。在每次递归中,选取数组中随机的一个元素作为枢纽元,并将数组分为左右两部分,然后对其中一部分进行递归,直到pivot的位置为k或者只有一个元素。