如何求数组中的 TOP k

本文阅读 1 分钟
首页 知识库 正文

取数组中前 k 个数做小顶堆,堆化
数组中的其它数逐一与堆顶元素比较,若大于堆顶元素,则插入该数
时间复杂度 O(nlg(k))
实现一个优先队列类,默认大顶堆,传入(x,y)=>x>y 比较函数则为小顶堆。 首先将前 k 个数 insert,之后的数字如果大于栈顶元素(栈顶元素为堆中最小值),delTop 删除栈顶元素,然后 insert 该数。 维护一个 size 为 k 的小顶堆。 最后堆中元素即为数组中最大的 k 个元素。

  1. class PriorityQueue {
  2. constructor(
  3. // 默认大顶堆
  4. cmp = (x, y) => {
  5. return x < y;
  6. }
  7. ) {
  8. this.queue = [];
  9. this.N = 0;
  10. this.cmp = (i, j) => {
  11. return cmp(this.queue[i], this.queue[j]);
  12. };
  13. this.parent = function (x) {
  14. return Math.floor(x / 2);
  15. };
  16. this.left = function (x) {
  17. return x * 2;
  18. };
  19. this.right = function (x) {
  20. return x * 2 + 1;
  21. };
  22. this.exch = (x, y) => {
  23. let temp = this.queue[x];
  24. this.queue[x] = this.queue[y];
  25. this.queue[y] = temp;
  26. };
  27. }
  28. swim(k) {
  29. const { cmp, parent, exch } = this;
  30. while (k > 1 && cmp(parent(k), k)) {
  31. exch(parent(k), k);
  32. k = parent(k);
  33. }
  34. }
  35. sink(k) {
  36. const { left, right, exch, N, cmp } = this;
  37. while (left(k) <= N) {
  38. let older = left(k);
  39. if (right(k) <= N && cmp(older, right(k))) {
  40. older = right(k);
  41. }
  42. if (cmp(older, k)) break;
  43. exch(older, k);
  44. k = older;
  45. }
  46. }
  47. top() {
  48. return this.queue[1];
  49. }
  50. delTop() {
  51. const { queue, exch } = this;
  52. let top = queue[1];
  53. exch(1, this.N);
  54. queue.pop();
  55. this.N--;
  56. this.sink(1);
  57. return top;
  58. }
  59. insert(x) {
  60. this.N++;
  61. this.queue[this.N] = x;
  62. this.swim(this.N);
  63. }
  64. size() {
  65. return this.N;
  66. }
  67. }
  68. function TopK(arr, k) {
  69. // 传入cmp,设置为小顶堆
  70. let pq = new PriorityQueue((x, y) => x > y);
  71. let i = 0;
  72. for (i = 0; i < k; i++) {
  73. pq.insert(arr[i]);
  74. }
  75. for (; i < arr.length; i++) {
  76. if (arr[i] > pq.top()) {
  77. pq.delTop();
  78. pq.insert(arr[i]);
  79. }
  80. }
  81. console.log("TOP K应为:", arr.sort((a, b) => b - a).splice(0, k));
  82. console.log("求出的TOP k:");
  83. // 排序,整理,方便对照
  84. pq.queue.sort((a, b) => b - a).pop();
  85. console.log(pq.queue);
  86. }
  87. let arr = [10, 15, 2, 6, 4, 5, 7, 3, 6, 14, 3, 12, 14, 13, 16, 1, 8];
  88. TopK(arr, 10);
解压密码: detechn或detechn.com

免责声明

本站所有资源出自互联网收集整理,本站不参与制作,如果侵犯了您的合法权益,请联系本站我们会及时删除。

本站发布资源来源于互联网,可能存在水印或者引流等信息,请用户自行鉴别,做一个有主见和判断力的用户。

本站资源仅供研究、学习交流之用,若使用商业用途,请购买正版授权,否则产生的一切后果将由下载用户自行承担。

大数乘法和大数加法
« 上一篇 05-28
求给定数组中 N 个数相加之和为 sum 所有可能集合
下一篇 » 05-28

发表评论

惪特博客
  • 文章总数:
    18498 篇
  • 评论总数:
    53264 条
  • 标签总数:
    8869 个
  • 总浏览量:
    21816992 次
  • 最后更新:
    6天前

最多点赞

随便看看

标签TAG