如何求数组中的 TOP k
取数组中前 k 个数做小顶堆,堆化
数组中的其它数逐一与堆顶元素比较,若大于堆顶元素,则插入该数
时间复杂度 O(nlg(k))
实现一个优先队列类,默认大顶堆,传入(x,y)=>x>y 比较函数则为小顶堆。 首先将前 k 个数 insert,之后的数字如果大于栈顶元素(栈顶元素为堆中最小值),delTop 删除栈顶元素,然后 insert 该数。 维护一个 size 为 k 的小顶堆。 最后堆中元素即为数组中最大的 k 个元素。
class PriorityQueue {
constructor(
// 默认大顶堆
cmp = (x, y) => {
return x < y;
}
) {
this.queue = [];
this.N = 0;
this.cmp = (i, j) => {
return cmp(this.queue[i], this.queue[j]);
};
this.parent = function (x) {
return Math.floor(x / 2);
};
this.left = function (x) {
return x * 2;
};
this.right = function (x) {
return x * 2 + 1;
};
this.exch = (x, y) => {
let temp = this.queue[x];
this.queue[x] = this.queue[y];
this.queue[y] = temp;
};
}
swim(k) {
const { cmp, parent, exch } = this;
while (k > 1 && cmp(parent(k), k)) {
exch(parent(k), k);
k = parent(k);
}
}
sink(k) {
const { left, right, exch, N, cmp } = this;
while (left(k) <= N) {
let older = left(k);
if (right(k) <= N && cmp(older, right(k))) {
older = right(k);
}
if (cmp(older, k)) break;
exch(older, k);
k = older;
}
}
top() {
return this.queue[1];
}
delTop() {
const { queue, exch } = this;
let top = queue[1];
exch(1, this.N);
queue.pop();
this.N--;
this.sink(1);
return top;
}
insert(x) {
this.N++;
this.queue[this.N] = x;
this.swim(this.N);
}
size() {
return this.N;
}
}
function TopK(arr, k) {
// 传入cmp,设置为小顶堆
let pq = new PriorityQueue((x, y) => x > y);
let i = 0;
for (i = 0; i < k; i++) {
pq.insert(arr[i]);
}
for (; i < arr.length; i++) {
if (arr[i] > pq.top()) {
pq.delTop();
pq.insert(arr[i]);
}
}
console.log("TOP K应为:", arr.sort((a, b) => b - a).splice(0, k));
console.log("求出的TOP k:");
// 排序,整理,方便对照
pq.queue.sort((a, b) => b - a).pop();
console.log(pq.queue);
}
let arr = [10, 15, 2, 6, 4, 5, 7, 3, 6, 14, 3, 12, 14, 13, 16, 1, 8];
TopK(arr, 10);
解压密码: detechn或detechn.com
免责声明
本站所有资源出自互联网收集整理,本站不参与制作,如果侵犯了您的合法权益,请联系本站我们会及时删除。
本站发布资源来源于互联网,可能存在水印或者引流等信息,请用户自行鉴别,做一个有主见和判断力的用户。
本站资源仅供研究、学习交流之用,若使用商业用途,请购买正版授权,否则产生的一切后果将由下载用户自行承担。