当前位置:   article > 正文

LeetCode 215. 数组中的第K个最大元素——Python实现(堆排序、快速排序)_数组中的第k个最大元素 leetcode python

数组中的第k个最大元素 leetcode python

1、用堆排序的方法

  1. # -*- coding: utf-8 -*-
  2. """
  3. @File : heap_find_kth_largest.py
  4. @Author: zhang_san
  5. @Time : 2020/8/28 19:54
  6. @des : 在未排序的数组中找到第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。
  7. 即:在数组进行降序排列之后,取 第 k 个位置上的值。这里不考虑重复的情况,比如排序后为[6, 5, 5, 4, 3, 2, 1],这里
  8. 的第 4 个最大的元素就是 4。
  9. 所以这种情况,用排序算法是最好的。最直接的方式是使用大堆排序,这样当找到第 k 个最大的值的时候就可以停止继续排序了。
  10. """
  11. class Solution:
  12. def findKthLargest(self, nums, k: int) -> int:
  13. def heap_sort(nums, root, last_index):
  14. left = 2 * root + 1
  15. while left <= last_index:
  16. # 如果左节点刚好是最后一个节点,则只比较root和left这两个节点,并且可以停止继续向下比较了
  17. if left == last_index:
  18. if nums[left] > nums[root]:
  19. nums[left], nums[root] = nums[root], nums[left]
  20. break
  21. # 如果当前root节点的子节点不是最后一个节点,则获取其子节点里更大的那个节点,然后跟root节点的值对比
  22. if nums[left + 1] > nums[left]: # 如果右子节点比左子节点大,那么交换右子节点
  23. left += 1
  24. # 对比root节点和子节点中比较大的节点,如果当前节点比其左右子节点都大,那么不需要再继续向下进行比较了,可以跳出了
  25. if nums[root] < nums[left]:
  26. nums[root], nums[left] = nums[left], nums[root]
  27. root = left
  28. left = 2 * root + 1
  29. else:
  30. break
  31. # 创建一个大根堆,大根堆得每颗子树也是大根堆,所以,从最后一个有子节点的非叶子节点开始,往前遍历,形成大根堆
  32. for i in range(int((len(nums)-1)/2), -1, -1):
  33. heap_sort(nums, i, len(nums) - 1)
  34. # 在大根堆的基础上交换第一个节点个最后一个节点
  35. for last_index in range(len(nums) - 1, -1, -1):
  36. nums[0], nums[last_index] = nums[last_index], nums[0]
  37. k -= 1
  38. if k == 0:
  39. return nums[last_index]
  40. heap_sort(nums, 0, last_index - 1)
  41. nums = [3, 2, 3, 1, 2, 4, 5, 5, 6]
  42. s = Solution()
  43. print(s.findKthLargest(nums, 1))

2、用快速排序的方法

  1. # -*- coding: utf-8 -*-
  2. """
  3. @File : quick_find_kth_largest.py
  4. @Author: zhang_san
  5. @Time : 2020/8/30 15:59
  6. @des : 用快速排序的思想。
  7. """
  8. import random
  9. class Solution:
  10. def findKthLargest(self, nums, k: int) -> int:
  11. def partition(nums, left, right):
  12. # 选择一个pivot点
  13. p = random.randint(left, right)
  14. nums[p], nums[left] = nums[left], nums[p]
  15. p = left
  16. # 进行快速排序, left始终指向的是最后一个小于pivot数的位置,所以最后要进行交换
  17. while left < right:
  18. if nums[right] < nums[p]:
  19. left += 1
  20. nums[left], nums[right] = nums[right], nums[left]
  21. else:
  22. right -= 1
  23. nums[p], nums[left] = nums[left], nums[p]
  24. return left
  25. target = len(nums) - k
  26. left, right = 0, len(nums) - 1
  27. while True:
  28. pivot = partition(nums, left, right)
  29. # 如果找到了就直接返回相应位置的值
  30. if pivot == target:
  31. return nums[target]
  32. # 如果没找到,则比较当前pivot与target的大小,缩小搜索的范围,并继续寻找合适的pivot
  33. if target < pivot:
  34. right = pivot - 1
  35. else:
  36. left = pivot + 1
  37. nums = [3, 2, 3, 1, 2, 4, 5, 5, 6]
  38. s = Solution()
  39. print(s.findKthLargest(nums, 4))

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/209798
推荐阅读
相关标签
  

闽ICP备14008679号