原题链接
. - 力扣(LeetCode)
思路
快速排序思路
快速排序中有一个partition函数,作用是以当前子数组的第一个元素为哨兵,将小于它的元素移到它之前,大于它的元素移到它之后,最后返回哨兵的位置。哨兵的位置不会再发生变动,是最后排好序的位置。哨兵的位置如果正好是len(nums)-k,则返回哨兵值。 如果哨兵的位置小len(nums)-k,那么哨兵右侧的子数组继续快排,反之,哨兵左侧的子数组进行快排。
堆排序思路
思路很简单,建立一个最小堆,弹出前len(nums)-k个元素,再弹出一次,得到的就是第k大的元素。堆排序这里我写了两种实现,一种是抄了捷径,用了python的heapq模块,代码十分简洁,但是时间效率并不高(虽然也通过了)。另一种是用数组模拟最小堆。
代码
快速排序代码
'''
归并排序解法
'''
from typing import Listclass Solution:def partition(self,nums: List[int],left:int,right:int) -> int:mid = left + (right-left)//2if (nums[left] <= nums[mid] <= nums[right]) or (nums[right] <= nums[mid] <= nums[left]):nums[left],nums[mid] = nums[mid],nums[left]elif (nums[left] <= nums[right] <= nums[mid]) or (nums[mid] <= nums[right] <= nums[left]):nums[left],nums[right] = nums[right],nums[left]i = leftj = rightwhile i < j:while nums[j] >= nums[left] and i < j:j -= 1while nums[i] <= nums[left] and i < j:i += 1nums[i],nums[j] = nums[j],nums[i]nums[i],nums[left] = nums[left],nums[i]return idef quick_sort_until_k(self,nums: List[int],left:int,right:int,k:int)->int:# print('left :',left,', right:',right)if left >= right:return nums[left]pivot = self.partition(nums,left,right)# print('pivot :',pivot)if pivot == k:return nums[pivot]elif pivot < k:return self.quick_sort_until_k(nums,pivot+1,right,k)else:return self.quick_sort_until_k(nums,left,pivot-1,k)def findKthLargest(self, nums: List[int], k: int) -> int:return self.quick_sort_until_k(nums,0,len(nums)-1,len(nums)-k)def main():solu = Solution()nums = [3,2,1,5,6,4]k = 2ans = solu.findKthLargest(nums,k)print(ans)# print(*nums)if __name__ == '__main__':main()
堆排序代码(heapq)
'''
堆排序解法
'''
from typing import List
import heapqclass Solution:def findKthLargest(self, nums: List[int], k: int) -> int:heapq.heapify(nums)for i in range(len(nums)-k):heapq.heappop(nums)return heapq.heappop(nums)def main():solu = Solution()nums = [3,2,3,1,2,4,5,5,6]k = 4ans = solu.findKthLargest(nums,k)print(ans)# print(*nums)if __name__ == '__main__':main()
堆排序代码(数组模拟最小堆)
'''
Input:
40 2 33 26 35 8 8 26 29 2
5
Answer:
26
'''
from typing import Listclass Solution:def down(self,heap:List[int],size:int,k:int):t = kif 2*k <= size and heap[2*k] < heap[t]:t = 2*kif 2*k+1 <= size and heap[2*k+1] < heap[t]:t = 2*k+1if t != k:heap[t],heap[k] = heap[k],heap[t]self.down(heap,size,t)def findKthLargest(self, nums: List[int], k: int) -> int:size = len(nums)heap = [0] + numsfor i in range(size//2,0,-1):self.down(heap,size,i)while size>k: # 最后堆中应该剩余的元素个数# print(heap[1],end=' ')heap[1] = heap[size]size -= 1self.down(heap,size,1)return heap[1]def main():s = Solution()a = [3,2,1,5,6,4]k = 2ans = s.findKthLargest(a,k)print(ans)if __name__ == "__main__":main()