基于堆与AdjustDown的TOP-K问题
TIPS
![](https://img-blog.csdnimg.cn/img_convert/398a00ad0c593c010e54bcfeafc59b6e.png)
![](https://img-blog.csdnimg.cn/img_convert/0fca35ce8b9ba3ae5f5c96ac4e1092e3.png)
TOP-K问题
TOP-K问题:就是说现在比如说有n个数据,然后需要从这n个数据里面找到最大的或最小的前k个。
一般来讲思路的话就是:先把这n个数据给他建一个堆,建堆完成之后,然后就去调堆,然后大概只需要调k次,然后就可以把前k个数据给他找到。
但比如说这个N它有时候会很大很大,比如说100亿,那这样的话100亿整数大概需要占40gb的内存。如果说还是按上面这个方法去做的话,光去建一个堆就要去申请40gb的内存,不可能啊。1G大约10亿字节
比如说现在n是100亿,也就是说有100亿个整数,然后比如说需要找到前50大的整数,该怎么办?
对于这种topk问题的话,实际上有个贼简单的方法。他现在题目中不是说有100亿个整数,然后需要去找到前50大的整数。我就直接利用他100亿个数据当中前50个数据先去建一个堆,而且是小根堆。然后去遍历剩下的所有数据,如果说那个数据比我这个堆顶的数据要大,就代替它进堆并向下调整Adjustadown。
这个方法他真正厉害的地方就在于他是一个小根堆。因为如果这样子的话,最大的前k个数一定能够进堆,就是说不存在,比如说有一个特别特别大的树放在堆顶,然后阻挡最大的前k个数进入。因为首先我这个堆里面的数据总共也就是k一个,其次就是这是一个小根堆,比较大的树它都是在堆底,就意味着在堆顶上面的数据是最小的。
如果说我要从非常非常非常多的数据当中找到前k个最小的数据,那我这时候就要建一个大根堆(有k个节点)。如果说我要求非常非常非常多的数据当中找到前k个最大的数据,那我这时候就要建一个小根堆(有k个节点)。
然后接下来依次去遍历所有的那些非常多的数据,然后与堆顶的元素进行比较,比如说我要求前k个最小的,我现在已经建了一个大根堆,如果说我遍历的元素比堆顶的元素要来的小,那就先去取代堆顶,然后接下来AdjustDown;如说我要求前k个最大的,我现在已经建了一个小根堆,如果说我遍历的元素比堆顶的元素要来的大,那就先去取代堆顶,然后接下来AdjustDown。这个与之前的堆排序有点差不多,都是有点逆直觉:比如说在堆排序当中,如果我要升序排列,就要建大根堆;如果说我要降序排列,就要减小根堆
然后popk问题不要与堆排序问题扯到一起,因为这个的话只涉及到建堆AdjustDown,并没有涉及到调堆。但如果说有额外要求的话,说在很多很多数据当中,求出前k个最小的数据,并且对于这k个数据也要进行排序的话,那么这时候就要额外加上堆排序的调堆
![](https://img-blog.csdnimg.cn/img_convert/38c0bbb82b2fd56645b1a3bafc17a836.png)
TOP-K问题的演示解决
这个先必须得有
void Swap(int* p1, int* p2)
{assert(p1 && p2);int tmp = *p1;*p1 = *p2;*p2 = tmp;
}
void AdjustDown(int* a, int parent, int n)
{assert(a);int child = 2 * parent + 1;while (child < n){if (child+1<n && a[child] < a[child + 1]){child++;}if (a[parent] < a[child]){Swap(a + parent, a + child);parent = child;child = 2 * parent + 1;}else{break;}}
}
造数据
#define ALL_NUMBER 10000000
#define SELECT_NUMBER 10
void CreateNumber()
{srand((unsigned int)time(NULL));FILE* pf = fopen("test.txt", "w");assert(pf);for (int i = 0; i < ALL_NUMBER; i++){fprintf(pf, "%d", rand() * 12345 % 1000000);}fclose(pf);pf = NULL;
}
TOP-K过程
void PrintPopK()
{FILE* pf = fopen("text.txt", "r");assert(pf);//建堆int arr[SELECT_NUMBER] = { 0 };for (int i = 0; i < SELECT_NUMBER; i++){fscanf(pf, "%d", &arr[i]);}for (int i = (SELECT_NUMBER - 1 - 1) / 2; i >= 0; i--){AdjustDown(arr, i, SELECT_NUMBER);}//遍历所有数据,看能否入堆int val;int ret;while ((ret = fscanf(pf, "%d", &val)) != EOF){if (val > arr[0]){arr[0] = val;AdjustDown(arr, 0, SELECT_NUMBER);}}//此刻,前k小的数已经在堆里面了,我还想排序一下int end = SELECT_NUMBER - 1;while (end > 0){Swap(arr + 0, arr + end);AdjustDown(arr, 0, end);end--;}//最终打印结果for (int i = 0; i < SELECT_NUMBER; i++){printf("%d ", arr[i]);}fclose(pf);pf = NULL;
}
总代码
#define ALL_NUMBER 1000000
#define SELECT_NUMBER 10
void CreateNumber()
{FILE* pf = fopen("text.txt", "w");assert(pf);for (int i = 0; i < ALL_NUMBER; i++){fprintf(pf, "%d\n", rand() * (rand()%10000) % 1000000);}fclose(pf);pf = NULL;
}void PrintPopK()
{FILE* pf = fopen("text.txt", "r");assert(pf);//建堆int arr[SELECT_NUMBER] = { 0 };for (int i = 0; i < SELECT_NUMBER; i++){fscanf(pf, "%d", &arr[i]);}for (int i = (SELECT_NUMBER - 1 - 1) / 2; i >= 0; i--){AdjustDown(arr, i, SELECT_NUMBER);}//遍历所有数据,看能否入堆int val;int ret;while ((ret = fscanf(pf, "%d", &val)) != EOF){if (val > arr[0]){arr[0] = val;AdjustDown(arr, 0, SELECT_NUMBER);}}//此刻,前k小的数已经在堆里面了,我还想排序一下int end = SELECT_NUMBER - 1;while (end > 0){Swap(arr + 0, arr + end);AdjustDown(arr, 0, end);end--;}//最终打印结果for (int i = 0; i < SELECT_NUMBER; i++){printf("%d ", arr[i]);}fclose(pf);pf = NULL;
}int main()
{srand((unsigned int)time(NULL));CreateNumber();PrintPopK();return 0;
}
体悟:
TOP-K问题他主要就是利用在堆当中所有的元素中堆顶是最值,因此每次就要去堆顶比较,并不断试图去代替他,一旦把他代替了之后,堆被破坏了,这时候还要复原回堆,然后再去利用堆着那个特别厉害的性质(堆顶元素是所有元素当中的最值)
相关文章:
![](https://img-blog.csdnimg.cn/img_convert/38c0bbb82b2fd56645b1a3bafc17a836.png)
基于堆与AdjustDown的TOP-K问题
TIPSTOP-K问题TOP-K问题:就是说现在比如说有n个数据,然后需要从这n个数据里面找到最大的或最小的前k个。一般来讲思路的话就是:先把这n个数据给他建一个堆,建堆完成之后,然后就去调堆,然后大概只需要调k次&…...
![](https://upic.fenxiangbe.com/uPic/2023/03/23/image-20230323191424001.png)
在CentOS上安装Docker引擎
1,先决条件#### 1-1操作系统要求1-2 卸载旧版本 2,安装方法2-1使用存储库安装设置存储库安装 Docker 引擎 本文永久更新地址: 官方地址:https://docs.docker.com/engine/install/centos/ 1,先决条件 #### 1-1操作系统要求 要安装 Docker Engine,您需要…...
![](https://img-blog.csdnimg.cn/ef751b0573a74d0c89769c9eb8a0111e.jpeg)
【10】核心易中期刊推荐——模式识别与机器学习
🚀🚀🚀NEW!!!核心易中期刊推荐栏目来啦 ~ 📚🍀 核心期刊在国内的应用范围非常广,核心期刊发表论文是国内很多作者晋升的硬性要求,并且在国内属于顶尖论文发表,具有很高的学术价值。在中文核心目录体系中,权威代表有CSSCI、CSCD和北大核心。其中,中文期刊的数…...
![](https://www.ngui.cc/images/no-images.jpg)
【数据结构】并查集
目录 一:用途 二:实现 O(1) 三:例题 例题1:集合 例题2:连通图无向 例题3:acwing 240 食物链 一:用途 将两个集合合并询问两个元素是否在一个集合当中 二:实现 O(1) 每…...
![](https://www.ngui.cc/images/no-images.jpg)
软考--网络攻击分类
网络攻击的主要手段包括口令入侵、放置特洛伊木马程序、拒绝服务(DoS)攻击、端口扫描、网络监听、欺骗攻击和电子邮件攻击等。口令入侵是指使用某些合法用户的账号和口令登录到目的主机,然后再实施攻击活动。特洛伊木马(Trojans)程序常被伪装…...
![](https://img-blog.csdnimg.cn/f8b284a4e903400a9f74036e9221054b.jpeg#pic_center)
蓝桥杯刷题冲刺 | 倒计时17天
作者:指针不指南吗 专栏:蓝桥杯倒计时冲刺 🐾马上就要蓝桥杯了,最后的这几天尤为重要,不可懈怠哦🐾 文章目录1.长草2.分考场1.长草 题目 链接: 长草 - 蓝桥云课 (lanqiao.cn) 题目描述 小明有一…...
![](https://img-blog.csdnimg.cn/88848a17a762461fb3e308fca286aefc.png)
冲击蓝桥杯-并查集,前缀和,字符串
目录 前言 一、并查集 1、并查集的合并(带路径压缩) 2、询问是否为同一个集合 3、例题 二、前缀和 1 、前缀和是什么 2、经典题目 三- 字符串处理 1、字符串的插入 2、字符串转化为int类型 3、字符反转 前言 并查集合前缀,字符串…...
![](https://img-blog.csdnimg.cn/85c27429cfa042b789381d1d350a840d.png)
【matlab学习笔记】线性方程组求解方法
线性方程组求解方法2.1 求逆法实现方式例子2.2 分解法LU分解(Doolittle分解)实现方法例子QR分解法实现方法例子Cholesky 分解法实现方法例子奇异值分解法实现方法例子Hessenberg 分解实现方法例子Schur 分解实现方法例子2.3 迭代法逐次迭代法里查森迭代法…...
![](https://img-blog.csdnimg.cn/ebd6368985ad4404acfc46a2de000eae.gif)
Python带你一键下载到最新章节,不付费也能看
前言 大家早好、午好、晚好吖 ❤ ~欢迎光临本文章 完整源码、素材皆可点击文章下方名片获取此处跳转 开发环境: python 3.8 运行代码 pycharm 2022.3 辅助敲代码 requests 发送请求/第三方模块 模块安装:win R 输入cmd 输入安装命令 pip install 模块名 如果…...
![](https://img-blog.csdnimg.cn/acd5781724bb4285b1504f67f918b359.png)
【sentinel】熔断降级规则详解及源码分析
概述 除了流量控制以外,对调用链路中不稳定的资源进行熔断降级也是保障高可用的重要措施之一。一个服务常常会调用别的模块,可能是另外的一个远程服务、数据库,或者第三方API等。例如,支付的时候,可能需要远程调用银联…...
![](https://www.ngui.cc/images/no-images.jpg)
ffplay源码分析-main函数入口分析
ffplay源码分析-main函数入口分析 基于ffmpeg6.0源码分析。 流程 使用ffplay播放视频文件,会触发main函数的调用。main函数中会进行以下操作: 从命令行中解析日志级别、日志是否需要落文件、是否要输出banner信息。banner信息包含版权、库的版本。注…...
![](https://img-blog.csdnimg.cn/img_convert/5f2e6a76ab868532793d7586f1920a0f.png)
C++三种继承方式
C继承的一般语法为:class 派生类名:[继承方式] 基类名{派生类新增加的成员};继承方式限定了基类成员在派生类中的访问权限,包括 public(公有的)、private(私有的)和 protected&#…...
![](https://img-blog.csdnimg.cn/4f90db9be93a48b29f3b63e9a789cc7f.png)
【Android -- 软技能】《软技能:代码之外的生存指南》之好书推荐(一)
前言 这是一本由美国的一个软件开发人员写的,但书中除了有 Java 、C# 几个单词外,没有一行代码。 因为这本书讲的是代码之外的东西。 文章目录结构: 1. 职业 从业心态:说白了就是要有责任心,把每份工作要当成是自…...
![](https://www.ngui.cc/images/no-images.jpg)
Nginx可视化管理工具 - Nginx Proxy Manager
一、介绍 nginx-proxy-manager 是一个反向代理管理系统,它基于Nginx,具有漂亮干净的 Web UI。还可以获得受信任的 SSL 证书,并通过单独的配置、自定义和入侵保护来管理多个代理。 其官网地址如下: https://nginxproxymanager.com/ 二、安装 第一步:192.168.1.108服务…...
![](https://www.ngui.cc/images/no-images.jpg)
https是如何保证安全的
在学习http与https的区别的时候,我们通常从以下几点出发:http是超文本传输协议,是明文传输,有安全风险,https在TCP和http网络层之间加入了SSL/TLS安全协议,使得报文能够加密传输http连接简单,三…...
![](https://www.ngui.cc/images/no-images.jpg)
ubuntu下使用GCC开发单片机的过程
以下是一个简单的单片机C程序示例,实现的功能是控制LED灯的闪烁: #include <reg52.h> // 导入单片机的寄存器定义void main() {while(1) { // 无限循环P1 = 0x00; // P1口输出低电平delay(1000); // 延时1秒P1 = 0xff; // P1口输出高电平delay(1000); // 延时1秒…...
![](https://img-blog.csdnimg.cn/7b51f358abf14106bb9807cde48325fc.png)
人工智能能否取代软硬件开发工程师
版权声明 本文原创作者:谷哥的小弟作者博客地址:http://blog.csdn.net/lfdfhl 人工智能发展趋势 随着AI技术的不断发展,它正在改变我们的生活方式、商业模式和工作方式。人工智能技术的发展一直处于快速变化和持续创新的状态,以下…...
![](https://www.ngui.cc/images/no-images.jpg)
BPI-R3开发板 - uboot编译
一. 获取源码 https://github.com/mtk-openwrt/u-boot 二. 编译步骤 编译环境为ubuntu 18.04。交叉编译工具链我用的是openwrt编译生成的工具链,并设置到环境变量,如下: export PATH$PATH:/root/mt8976/BPI-R3-OPENWRT-V21.02.3-main/staging…...
![](https://img-blog.csdnimg.cn/img_convert/dee99cdfc5c2cfa3df82b90f978a4ef1.webp?x-oss-process=image/format,png)
优秀程序员的5个特征,你在第几层?
每个人程序员都对未来的职业发展有着憧憬和规划,要做架构师、要做技术总监、要做CTO。但现实总是复杂的,日复一日的工作与生活总能让人一次又一次地陷入迷茫。大部分原因就是对职业发展轨迹和自我能力提升的一般规律缺乏认识,做事找不到方向或…...
![](https://img-blog.csdnimg.cn/420c67c057174a8784d94c25e549704f.png)
JAVA Session会话 Thymeleaf - 视图模板技术配置步骤
JAVAWebSession会话会话跟踪技术session保存作用域Thymeleaf - 视图模板技术配置过程Session会话 HTTP是无状态的:服务器无法区分这两个请求是同一个客户端发过来的,还是不同的客户端发过来的 现实问题:第一次请求是添加商品到购物车&#x…...
![](https://www.ngui.cc/images/no-images.jpg)
Linux编译cpprestsdk库
本文用的Linux系统为Ubuntu22.04,自带GCC11.3.0。 依赖 ①编译需要boost库,本文用的库版本为boost-1.82.0.beta1.tar.gz。 ②编译需要openssl库,这里使用的版本为openssl-1.1.1s.tar.gz。 ③编译需要cmake库,本文使用的是cmake-3…...
![](https://img-blog.csdnimg.cn/c4e569fe36c349399afe29322bfc5c83.png)
算法的时间复杂度和空间复杂度
目录 1 如何衡量一个算法的好坏 2.时间复杂度 2.1 时间复杂度的概念 2.2 大O的渐进表示法 2.3常见代码举例 2.3.1 Func2 O(N) 2.3.2 Func3 O(MN) 2.3.3 Func4 O(1) 2.3.4 Func5 strchr O(N) 2.3.5 Func6 冒泡排序 O(N^2) 2.3.6 Func7 二分…...
![](https://img-blog.csdnimg.cn/7f5b4bc9ddc5498483f4f0263c16d119.png)
基本认识vue3
一、基本搭建 项目搭建 使用 最新的 Vue3 TS Vite项目 执行命令 (本项目采用如下方式) npm create vitelatest my-vite-app --template vue-ts或者 运行项目 npm install npm run dev项目搭建初始化目录 新搭建的项目可能会遇到个问题…...
![](https://img-blog.csdnimg.cn/img_convert/ec7613eb1a115448276e30dc0bff3bd1.png)
HTTP/HTTPS协议认识
写在前面 这个博客我们要要讨论的是协议,主要是应用层.今天我们将正式认识HTTP和HTTPS,也要认识序列化和反序列化,内容比较多,但是不难 再谈协议 我们程序员写的一个个解决我们实际问题, 满足我们日常需求的网络程序, 都是在应用层,我们要完成下面三个步骤. sock的使用 定制…...
![](https://img-blog.csdnimg.cn/1391aa8239204a4580db049f4475498f.png)
【VScode】远程连接Linux
目录标题1. 安装扩展插件2. 在Linux上操作3. 确定Linux的IP地址4. 远程连接到Linux5. 实现免密码登录使用 VScode 远程编程与调试的时有会用到插件 Remote Development,使用这个插件可以在很多情况下代替 vim 直接远程修改与调试服务器上的代码,同时具备…...
![](https://img-blog.csdnimg.cn/1974fe2662da40059d545acbb5975343.png)
QT/C++调试技巧:内存泄漏检测
文章目录内存泄漏方案一方案二:CRT调试定位代码位置方法1方法2其它问题方案三:使用vs诊断工具方案四:使用工具VLD(Visio Leak Detector)方案五Cppcheck内存泄漏 内存泄漏:指的是在程序里动态申请的内存在使…...
![](https://img-blog.csdnimg.cn/5bc78713193645f78b39580d90381dd8.jpeg#pic_center)
【贪心算法】一文让你学会“贪心”(贪心算法详解及经典案例)
文章目录前言如何理解“贪心算法”?贪心算法实战分析1.分糖果2.钱币找零3.区间覆盖内容小结最后说一句🐱🐉作者简介:大家好,我是黑洞晓威,一名大二学生,希望和大家一起进步。 👿本…...
![](https://img-blog.csdnimg.cn/4388369dffe648eb857d99d391e9eaeb.png#pic_center)
【字体图标iconfont】字体图标部署流程+项目源码分析
今日,心情甚是烦闷,原由… 公司项目需要将字体图标做一些细微的调整,我一人分析了许久,看不大懂源码的逻辑,产生了自我怀疑。深吸一口气,重新鼓起勇气,调整心境,一下子豁然开朗&…...
![](https://img-blog.csdnimg.cn/0f4184b8dd76462198fe995e491f423f.gif)
2023最全的Web自动化测试介绍(建议收藏)
做测试的同学们都了解,做Web自动化,我们主要用Selenium或者是QTP。 有的人可能就会说,我没这个Java基础,没有Selenium基础,能行吗?测试虽然属于计算机行业,但其实并不需要太深入的编程知识&…...
![](https://img-blog.csdnimg.cn/7fc0b9a951f7402c8bb657effc8a1a9e.png)
jvm_根节点枚举安全点安全区域
1、可达性分析可以分成两个阶段 根节点枚举 从根节点开始遍历对象图 前文我们在介绍垃圾收集算法的时候,简单提到过:标记-整理算法(Mark-Compact)中的移动存活对象操作是一种极为负重的操作,必须全程暂停用户应用程序才能进行,像这…...
![](https://img-blog.csdnimg.cn/img_convert/5cc63a385a8c7fe355dea41dbd4e4cdb.gif)
网站建设公司运营经验/微信软文
Aviation turbofan starting model 涡扇发动机(Turbofan)即涡轮风扇发动机,来源于涡轮喷气发动机,主要是为了解决涡轮喷气发动机耗油率过高的问题。其结构特点是流过风扇的空气一部分进入压气机(内涵道),一部分进入由压气机外部通道(外涵道)流过,这部分气流不经过燃烧…...
![](/images/no-images.jpg)
二手车做的好的网站有哪些/百度信息流投放
接上篇:搜索引擎优化要领:8条辅助技巧(二) 六、正确使用重定向 有很多的原因,你可能会重定向的内容: 当移动一个旧站点到一个新的领域 指挥交通从一个网页到还有一个 移动通信从过期的页面到现有的页面 要移…...
![](/images/no-images.jpg)
网站的基础服务/新手如何学seo
Problem Description输入1个正整数n,计算1(12)(123)...(123...n)Input输入正整数n(多组数据)Output输出1(12)(123)...(123...n)的值(每组数据一行)Sample Input2Sample Output4#includeusing namespace std;int main(){int n,t;long sum;while(cin>>n){sum;t;for(int i;i…...
![](https://img-blog.csdnimg.cn/20200324230054275.png)
wordpress如何仿站/厦门人才网招聘
之前写了一篇文章讲述如何使用UaModeler,后来经一个读者朋友提醒,才发现它是商业软件,不交钱只能创建有限数量的节点… 后来本人去查找了一下相关的免费软件,找到2款:一个是freeOPCUA下的opcua-modeler,网…...
![](/images/no-images.jpg)
网页版qq空间电脑版/5g网络优化培训
接触了几个月的java,和javaweb. 感想1:发现生活顿时充实了很多,时间照样在过,日落日出,但是手里面有学的,有可以让自己开心地码出理想的效果,这是很不错的结局. 发现自己再也不回去和伙伴们撸,自以为我还是有天赋的,但是择重舍轻,果断戒了4年的DOTA,和刚盛行的LOL.因为我不在没…...
![](/images/no-images.jpg)
wordpress多麦/活动推广
${content}你输入的邮件地址曾经通过${type}激活了本站帐号,请使用${type}帐号直接登录。课程习题:提示请选择一个答案提交查看正确答案下一题${option}: ${content}{if multiple}{else}{/if}{if defined("xlist")&&!!xlist.length}{l…...