215. 数组中的第K个最大元素

给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。
请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。

输入: [3,2,3,1,2,4,5,5,6] 和 k = 2 输出: 5

  1. //基于快排的选择算法:时空On,logn
  2. func findKthLargest(nums []int, k int) int {
  3. rand.Seed(time.Now().UnixNano())
  4. return quickSelect(nums, 0, len(nums)-1, len(nums)-k)
  5. }
  6. func quickSelect(a []int, l, r, index int) int {
  7. q := randomPartition(a, l, r)
  8. if q == index {
  9. return a[q]
  10. } else if q < index {
  11. return quickSelect(a, q + 1, r, index)
  12. }
  13. return quickSelect(a, l, q - 1, index)
  14. }
  15. func randomPartition(a []int, l, r int) int {
  16. i := rand.Int() % (r - l + 1) + l
  17. a[i], a[r] = a[r], a[i]
  18. return partition(a, l, r)
  19. }
  20. func partition(a []int, l, r int) int {
  21. x := a[r]
  22. i := l - 1
  23. for j := l; j < r; j++ {
  24. if a[j] <= x {
  25. i++
  26. a[i], a[j] = a[j], a[i]
  27. }
  28. }
  29. a[i+1], a[r] = a[r], a[i+1]
  30. return i + 1
  31. }

image.png

  1. //基于堆排的选择方法:时空nlogn,logn
  2. func findKthLargest(nums []int, k int) int {
  3. heapSize := len(nums)
  4. buildMaxHeap(nums, heapSize)
  5. for i := len(nums) - 1; i >= len(nums) - k + 1; i-- {
  6. nums[0], nums[i] = nums[i], nums[0]
  7. heapSize--
  8. maxHeapify(nums, 0, heapSize)
  9. }
  10. return nums[0]
  11. }
  12. func buildMaxHeap(a []int, heapSize int) {
  13. for i := heapSize/2; i >= 0; i-- {
  14. maxHeapify(a, i, heapSize)
  15. }
  16. }
  17. func maxHeapify(a []int, i, heapSize int) {
  18. l, r, largest := i * 2 + 1, i * 2 + 2, i
  19. if l < heapSize && a[l] > a[largest] {
  20. largest = l
  21. }
  22. if r < heapSize && a[r] > a[largest] {
  23. largest = r
  24. }
  25. if largest != i {
  26. a[i], a[largest] = a[largest], a[i]
  27. maxHeapify(a, largest, heapSize)
  28. }
  29. }

image.png