215. 数组中的第K个最大元素
给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。
请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。
你必须设计并实现时间复杂度为 O(n) 的算法解决此问题。
示例 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 次删除操作后堆顶元素就是我们要找的答案。在很多语言中,都有优先队列或者堆的的容器可以直接使用,但是在面试中,面试官更倾向于让更面试者自己实现一个堆。所以建议读者掌握这里大根堆的实现方法,在这道题中尤其要搞懂「建堆」、「调整」和「删除」的过程。
def findKthLargest(nums,k):
nums.sort()
return nums[-k]
def sift(li, low, high):
# 堆最后一个元素位置high, low堆顶位置
i = low # 根节点位置
j = 2 * i + 1 # 左节点
temp = li[i] # 堆顶存起来
while j <= high: # 只要j位置有节点就一直循环
if j+1 <= hight and li[j+1] > li[j]: # 如果右节点存在并且比左节点大
j = j + 1 # j指向右节点
if li[j] > temp:
li[i] = li[j]
i = j # i j 位置替换
j = 2 * i + 1 # j网下继续调整
else:
li[i] = temp # 把temp放到父节点的位置
break
else:
li[i] = temp # 把temp放到叶子节点
def heap_sort(li):
n = len(li)
for i in range((n-1-1)//2, -1, -1): # 从最后一个节点的父节点的位置网前遍历
# i 表示建堆的时候调整的部分的根的下标
sift(li, i, n-1)
# 建堆完成
for i in range(n-1, -1, -1):
# i 指当前堆的最后一个元素的位置
li[0], li[i] = li[i], li[0]
sift(li, 0, i-1) # i-1是新的high
def findKthLargest(nums,k):
heap_sort(nums)
return nums[-k]
# 堆排序