testtopk.go 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. package main
  2. import (
  3. //"fmt"
  4. "math/rand"
  5. "time"
  6. )
  7. func findKthLargest(nums []int, k int) int {
  8. // 随机数种子
  9. rand.Seed(time.Now().UnixNano())
  10. return quickSelect(nums, 0, len(nums)-1, len(nums)-k)
  11. }
  12. // 快排剪枝
  13. func quickSelect(a []int, l, r, index int) int {
  14. q := randomPartition(a, l, r)
  15. if q == index {
  16. return a[q]
  17. } else if q < index {
  18. return quickSelect(a, q + 1, r, index)
  19. }
  20. return quickSelect(a, l, q - 1, index)
  21. }
  22. //随机中枢
  23. func randomPartition(a []int, l, r int) int {
  24. i := rand.Int() % (r - l + 1) + l
  25. // 因为把r的位置作为中枢,所以要交换
  26. a[i], a[r] = a[r], a[i]
  27. return partition(a, l, r)
  28. }
  29. //快排核心代码
  30. func partition(a []int, l, r int) int {
  31. // 因为传入的中枢是r位置
  32. x := a[r]
  33. // 先把i设置为l-1区间之外,保证每次更新先++再更新
  34. // i 的作用是记录小于中枢的区间
  35. i := l - 1
  36. // j不能遍历到r位置,因为r是中枢本身,查找完之后再做交换
  37. for j := l; j < r; j++ {
  38. // 遍历l到r,保证i左侧包括i位置记录的都小于等于x,右侧全部大于x
  39. if a[j] <= x {
  40. i++
  41. a[i], a[j] = a[j], a[i]
  42. }
  43. }
  44. // 最后遍历完交换r和i+1位置,把中枢放到正确的地方
  45. a[i+1], a[r] = a[r], a[i+1]
  46. return i + 1
  47. }
  48. func main() {
  49. array:=[]int{2,1,5,8,5,6,3,2,7}
  50. //tok 5
  51. print(findKthLargest(array, 1))
  52. }