赞
踩
在N个数中 找出最大或最小的前k个数,就是TopK算法。比如有一组数字,[1,2,3,4,5,6,7,8,9],这组数中最大的前 3(k)个数是 9,8,7。最小的 前3个数是 1,2,3。而TopK算法就是找出最大或者最小的前K个数。我们就用堆来实现。
之前讲解过如何写一个堆,博客链接 ,代码git链接。
今天我们就用这个堆,来实现TopK算法。
我们可以构建一个 有K个数的小堆,依次Push。
比如上面举的例子,1-9,找出最大的前3个数。
那么此时,K = 3, 找最大的前3个数,我们就构建小堆。
我们随机取3个数,2,6,9,放入小堆中。
随后我们拿剩下 N - K个数与堆顶进行比较,如果比堆顶大,那么就用这个数替换堆顶,随后进行向下调整。
第一次比较
第二次比较
第三次比较
上面三次都没有发生向下调整,因为堆顶的元素比它的两个孩子小,但下一次比较会发生向下调整!
第四次比较
向下调整后,我们就发现,堆顶元素变成了 5。
第五次比较和第四次比较一样,会发生向下调整。
第五次比较
第6次比较
比较完之后,我们会发现我们的堆是这样的
我们可以发现,7,8,9 就是我们 1 - 9 中 最大的前3个数。
那么代码我们就可以这样写。
void PrintTopK(int* data, int len, int k) { //建立一个堆 HP hp; HeapInit(&hp); //插入K个数据 for (int i = 0; i < k; i++) { HeapPush(&hp, data[i]); } //随后进行比较,是否比栈顶元素大 for (int i = k; i < len; i++) {
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。