一. 题目描述
在未排序的数组中找到第 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 ≤ 数组的长度。
二. 思路
1. 第一种思路是,先对数组进行排序,然后直接选取第K个数作为结果即可。这样的时间复杂度为O(nlog(n))
2. 第二种思路是,利用快速排序的思想,从数组 S 中随机找出一个元素 X,把数组分为两部分 Sa 和 Sb。Sa 中的元素大于等于 X,Sb 中元素小于 X。这时有两种情况:
- Sa 中元素的个数小于 k,则 Sb 中的第 k-|Sa| 个元素即为第k大数;
- Sa 中元素的个数大于等于 k,则返回 Sa 中的第 k 大数。时间复杂度近似为 O(n)
三. 代码
排序的代码就不贴了, 这里直接贴官方的关于思路二的代码:
class Solution:
# 采用快速排序方法,分成的数列左边大于右边
def findKthLargest(self, nums, k):
n = len(nums)
if (k > n):
return
index = self.quickSort(nums, 0, n-1, k)
return nums[index]
def quickSort(self, nums, l, r, k):
if l >= r:
return l
p = self.partition(nums, l, r)
if p + 1 == k:
return p
if p + 1 > k:
return self.quickSort(nums, l, p -1, k)
else:
return self.quickSort(nums, p + 1, r, k)
def partition(self, nums, l, r):
v = nums[l]
j = l
i = l + 1
while i <= r:
if nums[i] >= v:
nums[j+1],nums[i] = nums[i],nums[j+1]
j += 1
i += 1
nums[l], nums[j] = nums[j], nums[l]
return j
说明:使用快速排序的思想题速的主要原因是,这里采用了一种选择的策略,完成完整的快速排序,一般情况下的时间复杂度为O(nlog(n)),但明显,这个算法中,并不需要完成完整的快速排序,我们根据现有情况进行选择往哪一块走,那么就只对被选中的区域进行进一步的快速排序,而未选中的则直接放弃,所以在每次选择中,可以认为是减少了在本轮中一般的计算量,而每下一层,就会减少当前层一般的工作量,那么预期的时间复杂度为O(),接近O(n)。
官方的代码使用python编写的