版权声明:本文为博主原创文章,未经博主允许不得转载。有事联系:[email protected] https://blog.csdn.net/qq_17550379/article/details/82955914
在未排序的数组中找到第 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 ≤ 数组的长度。
解题思路
我们首先想到的办法就是,先对数组排序,然后直接取出第k
大的元素即可。
class Solution:
def findKthLargest(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: int
"""
nums.sort(reverse=True)
return nums[k - 1]
更为pythonic
的写法。
class Solution:
def findKthLargest(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: int
"""
return sorted(nums)[-k]
我们知道这种算法的时间复杂度很容易分析,是O(nlogn)
级别。
其实我们分析这个问题,我们发现这个问题实际上就是快速排序中的partition
操作。
class Solution:
def _partition(self, nums, l, r):
j = l
for i in range(l + 1, r + 1):
if nums[i] > nums[l]:
j += 1
nums[i], nums[j] = nums[j], nums[i]
nums[l], nums[j] = nums[j], nums[l]
return j
def _selection(self, nums, l, r, k):
if l == r:
return nums[k]
p = self._partition(nums, l, r)
if k == p:
return nums[p]
elif k < p:
return self._selection(nums, l, p - 1, k)
else:
return self._selection(nums, p + 1, r, k)
def findKthLargest(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: int
"""
return self._selection(nums, 0, len(nums) - 1, k - 1)
递归可也解决的问题,我们都应该思考一下怎么通过迭代的方式解决。
class Solution:
def _partition(self, nums, l, r):
j = l
for i in range(l + 1, r + 1):
if nums[i] > nums[l]:
j += 1
nums[i], nums[j] = nums[j], nums[i]
nums[l], nums[j] = nums[j], nums[l]
return j
def findKthLargest(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: int
"""
l, r = 0, len(nums) - 1
while 1:
p = self._partition(nums, l, r)
if k == p:
return nums[p]
elif k < p:
r = p - 1
else:
l = p + 1
实际编程中我们发现在_partition
中添加random
函数会更快。
def _partition(self, nums, l, r):
l, r = 0, len(nums) - 1
nums[l], nums[j] = nums[j], nums[l]
j = l
for i in range(l + 1, r + 1):
if nums[i] > nums[l]:
j += 1
nums[i], nums[j] = nums[j], nums[i]
nums[l], nums[j] = nums[j], nums[l]
return j
该问题的其他语言版本添加到了我的GitHub Leetcode
如有问题,希望大家指出!!!