本文介绍3种方法求前K个最大的数。
方法1 排序后求解
排序后求解,这种方法的复杂度是O(nlogn + k)
方法2 优先队列
使用优先队列(说实话,没太明白啥意思),但是我猜大致意思就是说用一个队列来保留当前前K个最大的值。
用堆排序的话,可以只找到前K个最大的数即可。
def findKthLargest(nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: int
"""
def adjust_heap(nums, end, begin):
root = begin
while True:
tmp = 2 * root + 1
if tmp > end:
break
if tmp+1 <= end and nums[tmp+1] > nums[tmp]:
tmp = tmp + 1
if nums[root] < nums[tmp]:
nums[root], nums[tmp] = nums[tmp], nums[root]
root = tmp
else:
break
end = len(nums) - 1
if end == 0:
return nums[0]
begin = end//2 - 1
for i in xrange(begin, -1, -1):
adjust_heap(nums, end, i)
print nums
for j in xrange(end, end-k, -1):
nums[j], nums[0] = nums[0], nums[j]
adjust_heap(nums, j, 0)
print nums
return nums[-k]
if __name__ == "__main__":
nums = [3, 2, 1, 5, 6, 4]
k = 2
print findKthLargest(nums, k)
方法3 利用快排的思想
def partition(nums, left, right):
pviot = nums[right]
p = left
for i in xrange(left, right):
# 由于本题是找第K大的数,因此这里是>
if nums[i] > pviot:
nums[i], nums[p] = nums[p], nums[i]
p += 1
nums[p], nums[right] = nums[right], nums[p]
return p
def findKthLargest2(nums, k):
if len(nums) == 1:
return nums[0]
left = 0
right = len(nums) - 1
p = partition(nums, left, right)
while left < right:
if k == p + 1:
return nums[p]
elif k < p + 1:
return findKthLargest2(nums[left:p], k)
else:
return findKthLargest2(nums[p+1:right+1], k-p-1)
def findKthLargest3(nums, k):
if len(nums) == 1:
return nums[0]
size = len(nums)
left = 0
right = len(nums) - 1
while left <= right:
p = partition(nums, left, right)
if k == p + 1
return nums[p]
elif k > p + 1:
left = p + 1
else:
right = p - 1
if __name__ == "__main__":
nums = [3, 2, 1, 5, 6, 4]
k = 2
print findKthLargest2(nums, k)
网友评论