TopK问题是指从n个数据中取前K个数据,在生活中的应用也有很多,如游戏中xxx的排行榜前10名等。在这篇博客中我将主要利用去解决TopK问题。

堆排序

首先我们需要建一个堆,然后我们再进行堆排序,排好序后直接取前K个就可以了。需要注意的是在使用堆排序的时候,我们需要确定我们要排升序还是降序。如果是升序的话,我们要建一个大根堆;如果是降序的话,我们要建一个小根堆思路:(可以结合图来进行分析) 这里我们以排降序为例子进行说明,建好小根堆后,我们将堆顶元素与堆中的最后一个元素进行互换   (让最小的元素换到最后面,以此来达到降序),此时最后一个元素就是最小的那个元素了,然后让堆的大小 - 1,也就是我们将最后一个元素从堆中踢出,可以将它看做已排好序的一个集合。然后再对这个堆进行向下调整算法,重新让它成为一个小根堆,然后重复这段操作,直到堆中只剩1个元素。堆排序的时间复杂度为O(n*logn)。

//向下调整算法
void AdjustDown(int* a, int n, int root)
{int parent = root;int child = 2 * parent + 1;while (child < n){//左孩子和右孩子进行比较,选出较小的【如果没有右孩子,不进行该比较】if (child + 1 < n && a[child] > a[child + 1]){child++;}//判断孩子节点和父节点【调成小堆】if (a[child] < a[parent]){int tmp = a[child];a[child] = a[parent];a[parent] = tmp;parent = child;child = 2 * child + 1;}else{break;}}
}void HeapCreate(Heap* hp, HpDataType* a, int sz)
{//堆的空间开辟和初始化hp->_a = (HpDataType*)malloc(sizeof(HpDataType)*sz);hp->_size = sz;hp->_capacity = sz;//数据的拷贝memcpy(hp->_a, a, sizeof(HpDataType)*sz);//堆的创建int i = 0;for (i = (sz - 1 - 1) / 2;i >= 0;--i){AdjustDown(hp->_a, sz, i);}
}void HeapSort(Heap* hp)
{int i = 0;for (i = hp->_size - 1; i > 0;--i){Swap(&hp->_a[i], &hp->_a[0]);AdjustDown(hp->_a, i, 0);}
}void PrintTopK(int* a, int n, int K)
{Heap hp;HeapCreate(&hp, a, K);HeapSort(&hp);int i = 0;for (i = 0; i < K; ++i){printf("%d ", hp._a[i]);}
}

建一个大小为n的堆

我们利用所给的n个数据去建一个大小为n的堆,如果求的是最大的K个数据,那么我们需要建大根堆;要求最小的K个数据,我们要建小根堆。这里我们以求最大的K个数据为例子,我们建一个大小为n的大根堆,然后这个堆的堆顶元素(HeapTop),然后再对将堆顶元素进行删除(HeapPop)的操作,然后再进行向下调整算法。要求最大的K个,那么只要循环K次即可。

HpDataType HeapTop(Heap* hp)
{return hp->_a[0];
}void HeapPop(Heap* hp)
{Swap(&hp->_a[0], &hp->_a[hp->_size - 1]);hp->_size--;//每进行完1次删除,都要进行1次向下调整AdjustDown(hp->_a, hp->_size, 0);
}void PrintTopK(int* a, int n, int K)
{Heap hp;HeapCreate(&hp, a, K);int i = 0;for (i = 0; i < K; ++i){printf("%d ", HeapTop(&hp));HeapPop(&hp);}
}

建一个大小为K的堆

这里我们以求最大的K个数据为例子。首先,我们先用一组数据中的前K个数据建一个小根堆,然后依次的用剩下的数据与小根堆的堆顶元素进行比较,如果该元素大于堆顶元素,那么将该元素替换为堆顶元素,随后再进行向下调整,使其保持小根堆,当所有元素都比较完后,小根堆中的K个元素就是这些数据中的最大的K个元素了。

void PrintTopK(int* a, int n, int K)
{Heap hp;//用前K个元素去建一个小根堆HeapCreate(&hp, a, K);//用剩下的元素与堆顶元素进行比较int i = 0;for (i = K; i < n; ++i){if (a[i] > HeapTop(&hp)){hp._a[0] = a[i];//替换堆顶元素AdjustDown(hp._a, K, 0);}}for (i = 0; i < K;++i){printf("%d ", hp._a[i]);}
}

TopK问题的三种解法相关推荐

  1. 关于某日访问次数最多的IP的topK问题的三种解法

    题目描述 在july大神的博客中,看到这样两道题: 1. 海量日志数据,提取出某日访问百度次数最多的那个IP. 2. 假设目前有一千万个记录(这些查询串的重复度比较高,虽然总数是1千万,但如果除去重复 ...

  2. [简单题]自定义取余(三种解法)C++实现

    题目链接: 点击打开原题链接 题目意思,就是标题意思. 第一种解法:(加法迭代)用加法来模拟这个(17行代码) int mod256WithoutMod(int number) {if (number ...

  3. jsp判断字符串相等_最长回文字符串三种解法

    先解释一下什么是回文字符串,比如说字符串"aba",无论是从先往后读取还是从后往前读取,结果都是一样的.当给定很长的字符串时,如何快速获取到最长的回文字符串,这也是大厂比较常见的算 ...

  4. 【三种解法】剑指 Offer 06. 从尾到头打印链表【附完整可运行代码】

    立志用最少的代码做最高效的表达 输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回). 示例 1: 输入:head = [1,3,2] 输出:[2,3,1] 限制: 0 <= 链表 ...

  5. 【三种解法】Not so Mobile UVA - 839_19行代码AC

    立志用最少的代码做最高效的表达 Before being an ubiquous communications gadget, a mobile was just a structure made o ...

  6. 【LeetCode】1. 盛最多水的容器:C#三种解法

    题目:https://leetcode-cn.com/problems/container-with-most-water/ 盛最多水的容器 难度:中等 给你 n 个非负整数 a1,a2,...,an ...

  7. 一只青蛙跳向三个台阶_青蛙跳台阶问题的三种解法

    题目:一只青蛙一次可以跳 1 级台阶,也可以跳 2 级.求该青蛙跳上一个 n 级的台阶总共有多少种跳法. 这道题还被 ITEye 放在了博文视点杯有奖答题活动里面. 我提供三种解法. 1.递归求解: ...

  8. 背包问题knapsack的三种解法(Python 和 C)

    最近研究了一下0-1背包问题,题目就不复述了,大家应该都知道的. 确切的说不是三种解法而是四种解法,下面我就一一写来. 0.枚举法 这种是最简单的一种做法,当然也是时间空间复杂度最大的方法,得到的肯定 ...

  9. 寻找两个有序数组的中位数(附上三种解法)

    目录 •写在前面 •题目 •解法一 •解法二 •解法三 •结束 •写在前面 这道题比较经典,我当时在做的时候,想出了两种解决方案,不过总感觉算法不够优美,所以找到了另一种我觉得非常精妙的解法,利用了K ...

最新文章

  1. python函数参数*arg和**kwargs分别代表什么?
  2. node2vec文献出处_社交网络分析(五)-Node2Vec
  3. asp.net 中ascx、asmx、ashx等文件类型说明
  4. python selenium T3
  5. C++语言基础 —— 顺序结构
  6. 如何制作自己的R包?
  7. 一行代码如何隐藏 Linux 进程?
  8. springboot支付宝微信支付对接总结
  9. yaml-cpp保存标定文件-Node/Emitter
  10. 【 OJ 】 HDOJ1048 明文加密问题 [ 42 ]
  11. 诚诚富众资讯1.02亿人次补偿式出游
  12. hive 转拼音udf_Hive 自定义UDF函数
  13. 平均年薪20W,自动化测试工程师这么吃香?
  14. 万维网互联网计算机网络的区别,互联网、局域网、万维网三者区别
  15. Power Supply---驱动框架
  16. 首富软件测试工资,测试你成为富豪 测试你天生是什么命
  17. 课程发布-添加课程信息
  18. NOIP2022游记
  19. 幸运抽奖java_java实现幸运抽奖系统
  20. Ajax,FormData

热门文章

  1. ovs partial offload
  2. KZGO-A-031/315比例减压阀控制器
  3. 利用TensorRT转换ResNet50
  4. 作为一名成年人的程序员,没必要刻意去交朋友
  5. RabbitMQ认知篇 - 优先级队列
  6. hackbar v2
  7. 帮我出一份正规的可以促使眉毛生长的办法,以达到浓眉的目的
  8. 手把手地写一个机器人仿真环境---RobotZen
  9. solidity智能合约面试题
  10. AWS中的HVM和PV格式的AMI的区别